Imported Upstream version 2.86 65/269265/1 upstream/2.86
authorSeonah Moon <seonah1.moon@samsung.com>
Wed, 12 Jan 2022 07:08:34 +0000 (16:08 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Wed, 12 Jan 2022 07:08:41 +0000 (16:08 +0900)
Change-Id: Ia335f0d8b027f8471c52e8dfdab59f3680422f10

68 files changed:
CHANGELOG
FAQ
Makefile
VERSION
bld/Android.mk
bld/get-version
contrib/lease-tools/dhcp_lease_time.c
contrib/lease-tools/dhcp_release.c
man/dnsmasq.8
po/de.po
po/es.po
po/fi.po
po/fr.po
po/id.po
po/it.po
po/no.po
po/pl.po
po/pt_BR.po
po/ro.po
src/arp.c
src/auth.c
src/blockdata.c
src/bpf.c
src/cache.c
src/config.h
src/conntrack.c
src/crypto.c
src/dbus.c
src/dhcp-common.c
src/dhcp-protocol.h
src/dhcp.c
src/dhcp6-protocol.h
src/dhcp6.c
src/dns-protocol.h
src/dnsmasq.c
src/dnsmasq.h
src/dnssec.c
src/domain-match.c [new file with mode: 0644]
src/domain.c
src/dump.c
src/edns0.c
src/forward.c
src/hash-questions.c [moved from src/hash_questions.c with 88% similarity]
src/helper.c
src/inotify.c
src/ip6addr.h
src/lease.c
src/log.c
src/loop.c
src/metrics.c
src/metrics.h
src/netlink.c
src/network.c
src/option.c
src/outpacket.c
src/pattern.c [new file with mode: 0644]
src/poll.c
src/radv-protocol.h
src/radv.c
src/rfc1035.c
src/rfc2131.c
src/rfc3315.c
src/rrfilter.c
src/slaac.c
src/tables.c
src/tftp.c
src/ubus.c
src/util.c

index b70bf26..5e54df9 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,183 @@
+version 2.86
+       Handle DHCPREBIND requests in the DHCPv6 server code.
+       Thanks to Aichun Li for spotting this omission, and the initial
+       patch.
+
+       Fix bug which caused dnsmasq to lose track of processes forked
+       to handle TCP DNS connections under heavy load. The code
+       checked that at least one free process table slot was
+       available before listening on TCP sockets, but didn't take
+       into account that more than one TCP connection could
+       arrive, so that check was not sufficient to ensure that
+       there would be slots for all new processes. It compounded
+       this error by silently failing to store the process when
+       it did run out of slots. Even when this bug is triggered,
+       all the right things happen, and answers are still returned.
+       Only under very exceptional circumstances, does the bug
+       manifest itself: see
+       https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2021q2/014976.html
+       Thanks to Tijs Van Buggenhout for finding the conditions under
+       which the bug manifests itself, and then working out
+       exactly what was going on.
+
+       Major rewrite of the DNS server and domain handling code.
+       This should be largely transparent, but it drastically
+       improves performance and reduces memory foot-print when
+       configuring large numbers domains of the form
+       local=/adserver.com/
+       or
+       local=/adserver.com/#
+       Lookup times now grow as log-to-base-2 of the number of domains,
+       rather than greater than linearly, as before.
+       The change makes multiple addresses associated with a domain work
+       address=/example.com/1.2.3.4
+       address=/example.com/5.6.7.8
+       It also handles multiple upstream servers for a domain better; using
+       the same try/retry algorithms as non domain-specific servers. This
+       also applies to DNSSEC-generated queries.
+       Finally, some of the oldest and gnarliest code in dnsmasq has had
+       a significant clean-up. It's far from perfect, but it _is_ better.
+
+       Revise resource handling for number of concurrent DNS queries. This
+       used to have a global limit, but that has a problem when using
+       different servers for different upstream domains. Queries which are
+       routed by domain to an upstream server which is not responding will
+       build up and trigger the limit, which breaks DNS service for
+       all other domains which could be handled by other servers. The
+       change is to make the limit per server-group, where a server group
+       is the set of servers configured for a particular domain. In the
+       common case, where only default servers are declared, there is
+       no effective change.
+
+       Improve efficiency of DNSSEC. The sharing point for DNSSEC RR data
+       used to be when it entered the cache, having been validated. After
+       that queries requiring the KEY or DS records would share the cached
+       values. There is a common case in dual-stack hosts that queries for
+       A and AAAA records for the same domain are made simultaneously.
+       If required keys were not in the cache, this would result in two
+       requests being sent upstream for the same key data (and all the
+       subsequent chain-of-trust queries.) Now we combine these requests
+       and elide the duplicates, resulting in fewer queries upstream
+       and better performance. To keep a better handle on what's
+       going on, the "extra" logging mode has been modified to associate
+       queries and answers  for DNSSEC queries in the same way as ordinary
+       queries. The requesting address and port have been removed from
+       DNSSEC logging lines, since this is no longer strictly defined.
+
+       Connection track mark based DNS query filtering. Thanks to
+       Etan Kissling for implementing this It extends query filtering
+       support beyond what is currently possible
+       with the `--ipset` configuration option, by adding support for:
+       1) Specifying allowlists on a per-client basis, based on their
+          associated Linux connection track mark.
+       2) Dynamic configuration of allowlists via Ubus.
+       3) Reporting when a DNS query resolves or is rejected via Ubus.
+       4) DNS name patterns containing wildcards.
+       Disallowed queries are not forwarded; they are rejected
+       with a REFUSED error code.
+
+       Allow smaller than 64 prefix lengths in synth-domain, with caveats.
+       --synth-domain=1234:4567::/56,example.com is now valid.
+
+       Make domains generated by --synth-domain appear in replies
+       when in authoritative mode.
+
+       Ensure CAP_NET_ADMIN capability is available when
+       conntrack is configured. Thanks to Yick Xie for spotting
+       the lack of this.
+
+       When --dhcp-hostsfile --dhcp-optsfile and --addn-hosts are
+       given a directory as argument, define the order in which
+       files within that directory are read (alphabetical order
+       of filename). Thanks to Ed Wildgoose for the initial patch
+       and motivation for this.
+
+       
+version 2.85
+        Fix problem with DNS retries in 2.83/2.84.
+        The new logic in 2.83/2.84 which merges distinct requests
+       for the same domain causes problems with clients which do
+       retries as distinct requests (differing IDs and/or source ports.)
+       The retries just get piggy-backed on the first, failed, request.
+        The logic is now changed so that distinct requests for repeated
+        queries still get merged into a single ID/source port, but
+       they now always trigger a re-try upstream.
+        Thanks to Nicholas Mu for his analysis.
+
+       Tweak sort order of tags in get-version. v2.84 sorts
+       before v2.83, but v2.83 sorts before v2.83rc1 and 2.83rc1
+       sorts before v2.83test1. This fixes the problem which lead
+       to 2.84 announcing itself as 2.84rc2.
+
+       Avoid treating a --dhcp-host which has an IPv6 address
+       as eligible for use with DHCPv4 on the grounds that it has
+       no address, and vice-versa. Thanks to Viktor Papp for
+       spotting the problem. (This bug was fixed was back in 2.67, and
+       then regressed in 2.81).
+
+       Add --dynamic-host option: A and AAAA records which take their
+       network part from the network of a local interface. Useful
+       for routers with dynamically prefixes. Thanks
+       to Fred F for the suggestion.
+
+       Teach --bogus-nxdomain and --ignore-address to take an IPv4 subnet.
+
+       Use random source ports where possible if source
+       addresses/interfaces in use.
+       CVE-2021-3448 applies. Thanks to Petr Menšík for spotting this.
+       It's possible to specify the source address or interface to be
+       used when contacting upstream name servers: server=8.8.8.8@1.2.3.4
+       or server=8.8.8.8@1.2.3.4#66 or server=8.8.8.8@eth0, and all of
+       these have, until now, used a single socket, bound to a fixed
+       port. This was originally done to allow an error (non-existent
+       interface, or non-local address) to be detected at start-up. This
+       means that any upstream servers specified in such a way don't use
+       random source ports, and are more susceptible to cache-poisoning
+       attacks.
+       We now use random ports where possible, even when the
+       source is specified, so server=8.8.8.8@1.2.3.4 or
+       server=8.8.8.8@eth0 will use random source
+       ports. server=8.8.8.8@1.2.3.4#66 or any use of --query-port will
+       use the explicitly configured port, and should only be done with
+       understanding of the security implications.
+       Note that this change changes non-existing interface, or non-local
+       source address errors from fatal to run-time. The error will be
+       logged and communication with the server not possible.
+
+       Change the method of allocation of random source ports for DNS.
+       Previously, without min-port or max-port configured, dnsmasq would
+       default to the compiled in defaults for those, which are 1024 and
+       65535. Now, when neither are configured, it defaults instead to
+       the kernel's ephemeral port range, which is typically
+       32768 to 60999 on Linux systems. This change eliminates the
+       possibility that dnsmasq may be using a registered port > 1024
+       when a long-running daemon starts up and wishes to claim it.
+       This change does likely slightly reduce the number of random ports
+       and therefore the protection from reply spoofing. The older
+       behaviour can be restored using the min-port and max-port config
+       switches should that be a concern.
+
+       Scale the size of the DNS random-port pool based on the
+       value of the --dns-forward-max configuration.
+
+       Tweak TFTP code to check sender of all received packets, as
+       specified in RFC 1350 para 4.
+
+       Support some wildcard matching of input tags to --tag-if.
+       Thanks to Geoff Back for the idea and the patch.
+
+       
+version 2.84
+       Fix a problem, introduced in 2.83, which could see DNS replies
+       being sent via the wrong socket. On machines running both
+       IPv4 and IPv6 this could result in sporadic messages of
+       the form "failed to send packet: Network is unreachable" and
+       the lost of the query. Since the error is sporadic and of
+       low probability, the client retry would normally succeed.
+
+       Change HAVE_NETTLEHASH compile-time to HAVE_CRYPTOHASH.
+
+
 version 2.83
        Use the values of --min-port and --max-port in outgoing
        TCP connections to upstream DNS servers.
@@ -19,13 +199,13 @@ version 2.83
 
        Handle multiple identical near simultaneous DNS queries better.
        Previously, such queries would all be forwarded
-       independently. This is, in theory, inefficent but in practise
+       independently. This is, in theory, inefficient but in practise
        not a problem, _except_ that is means that an answer for any
        of the forwarded queries will be accepted and cached.
        An attacker can send a query multiple times, and for each repeat,
        another {port, ID} becomes capable of accepting the answer he is
        sending in the blind, to random IDs and ports. The chance of a
-       succesful attack is therefore multiplied by the number of repeats
+       successful attack is therefore multiplied by the number of repeats
        of the query. The new behaviour detects repeated queries and
        merely stores the clients sending repeats so that when the
        first query completes, the answer can be sent to all the
diff --git a/FAQ b/FAQ
index fa22833..fbc6e1f 100644 (file)
--- a/FAQ
+++ b/FAQ
@@ -236,7 +236,7 @@ Q: What network types are supported by the DHCP server?
 A: Ethernet (and 802.11 wireless) are supported on all platforms. On
    Linux all network types (including FireWire) are supported.
 
-Q: What are these strange "bind-interface" and "bind-dynamic" options?
+Q: What are these strange "bind-interfaces" and "bind-dynamic" options?
 
 A: Dnsmasq from v2.63 can operate in one of three different "networking
    modes". This is unfortunate as it requires users configuring dnsmasq
index 7d2afd1..0cd592e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# dnsmasq is Copyright (c) 2000-2016 Simon Kelley
+# dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 #
 #  This program is free software; you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
@@ -63,8 +63,10 @@ ct_libs =       `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CON
 lua_cflags =    `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.2` 
 lua_libs =      `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.2` 
 nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC     $(PKG_CONFIG) --cflags 'nettle hogweed' \
+                                                        HAVE_CRYPTOHASH $(PKG_CONFIG) --cflags nettle \
                                                         HAVE_NETTLEHASH $(PKG_CONFIG) --cflags nettle`
 nettle_libs =   `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC     $(PKG_CONFIG) --libs 'nettle hogweed' \
+                                                        HAVE_CRYPTOHASH $(PKG_CONFIG) --libs nettle \
                                                         HAVE_NETTLEHASH $(PKG_CONFIG) --libs nettle`
 gmp_libs =      `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp`
 sunos_libs =    `if uname | grep SunOS >/dev/null 2>&1; then echo -lsocket -lnsl -lposix4; fi`
@@ -77,10 +79,10 @@ copts_conf = .copts_$(sum)
 objs = cache.o rfc1035.o util.o option.o forward.o network.o \
        dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
        helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
-       dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \
+       dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o pattern.o \
        domain.o dnssec.o blockdata.o tables.o loop.o inotify.o \
        poll.o rrfilter.o edns0.o arp.o crypto.o dump.o ubus.o \
-       metrics.o hash_questions.o
+       metrics.o hash-questions.o domain-match.o
 
 hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
        dns-protocol.h radv-protocol.h ip6addr.h metrics.h
diff --git a/VERSION b/VERSION
index 243b1db..81fd6fc 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
- (HEAD -> master, tag: v2.83)
+ (HEAD -> master, tag: v2.86)
index f924be9..917f8dc 100644 (file)
@@ -11,7 +11,8 @@ LOCAL_SRC_FILES :=  bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
                    radv.c slaac.c auth.c ipset.c domain.c \
                    dnssec.c dnssec-openssl.c blockdata.c tables.c \
                    loop.c inotify.c poll.c rrfilter.c edns0.c arp.c \
-                   crypto.c dump.c ubus.c metrics.c hash_questions.c
+                   crypto.c dump.c ubus.c metrics.c hash-questions.c \
+                    domain-match.c
 
 LOCAL_MODULE := dnsmasq
 
index e472aab..1f51768 100755 (executable)
@@ -9,7 +9,10 @@
 # If we can find one which matches $v[0-9].* then we assume it's
 # a version-number tag, else we just use the whole string.
 # If there is more than one v[0-9].* tag, sort them and use the
-# first. This favours, eg v2.63 over 2.63rc6.
+# first. The insane arguments to the sort command are to ensure
+# that, eg v2.64 comes before v2.63, but v2.63 comes before v2.63rc1
+# and v2.63rc1 comes before v2.63test1
+
 
 # Change directory to the toplevel source directory.
 if test -z "$1" || ! test -d "$1" || ! cd "$1"; then
@@ -28,7 +31,7 @@ else
      vers=`cat $1/VERSION | sed 's/[(), ]/,/ g' | tr ',' '\n' | grep ^v[0-9]`
 
      if [ $? -eq 0 ]; then
-         echo "${vers}" | sort -r | head -n 1 | sed 's/^v//'
+         echo "${vers}" | sort -k1.2,1.5Vr -k1.6,1.6 -k1.8,1.9Vr -k1.10,1.11Vr | head -n 1 | sed 's/^v//'
      else
          cat $1/VERSION
      fi
index 91edbfa..e2bad3c 100644 (file)
@@ -153,7 +153,11 @@ int main(int argc, char **argv)
       exit(1);
     }
  
-  lease.s_addr = inet_addr(argv[1]);
+  if (inet_pton(AF_INET, argv[1], &lease) < 1)
+    {
+      fprintf(stderr, "invalid address: %s\n", argv[1]);
+      exit(1);
+    }
    
   memset(&packet, 0, sizeof(packet));
  
@@ -176,8 +180,8 @@ int main(int argc, char **argv)
   
   *(p++) = OPTION_END;
  
-  dest.sin_family = AF_INET; 
-  dest.sin_addr.s_addr = inet_addr("127.0.0.1");
+  dest.sin_family = AF_INET;
+  (void)inet_pton(AF_INET, "127.0.0.1", &dest.sin_addr);
   dest.sin_port = ntohs(DHCP_SERVER_PORT);
   
   if (sendto(fd, &packet, sizeof(packet), 0, 
index 30e77c6..c1c835b 100644 (file)
@@ -288,13 +288,12 @@ int main(int argc, char **argv)
       exit(1);
     }
   
-  if (inet_addr(argv[2]) == INADDR_NONE)
+  if (inet_pton(AF_INET, argv[2], &lease.s_addr) < 1)
     {
       perror("invalid ip address");
       exit(1);
     }
   
-  lease.s_addr = inet_addr(argv[2]);
   server = find_interface(lease, nl, if_nametoindex(argv[1]), fd, &ifr);
   
   memset(&packet, 0, sizeof(packet));
index ac7c9fa..7ffccad 100644 (file)
@@ -1,4 +1,4 @@
-.TH DNSMASQ 8 2020-04-05
+.TH DNSMASQ 8 2021-08-16
 .SH NAME
 dnsmasq \- A lightweight DHCP and caching DNS server.
 .SH SYNOPSIS
@@ -55,7 +55,8 @@ Don't read the hostnames in /etc/hosts.
 .B \-H, --addn-hosts=<file>
 Additional hosts file. Read the specified file as well as /etc/hosts. If \fB--no-hosts\fP is given, read
 only the specified file. This option may be repeated for more than one
-additional hosts file. If a directory is given, then read all the files contained in that directory. 
+additional hosts file. If a directory is given, then read all the files contained in that directory
+in alphabetical order.
 .TP
 .B --hostsdir=<path>
 Read all the hosts files contained in the directory. New or changed files
@@ -135,6 +136,9 @@ running, will go exclusively to the file.) When logging to a file,
 dnsmasq will close and reopen the file when it receives SIGUSR2. This 
 allows the log file to be rotated without stopping dnsmasq.
 .TP
+.B --log-debug
+Enable extra logging intended for debugging rather than information.
+.TP
 .B --log-async[=<lines>]
 Enable asynchronous logging and optionally set the limit on the
 number of lines
@@ -181,7 +185,7 @@ OS: this was the default behaviour in versions prior to 2.43.
 .B --min-port=<port>
 Do not use ports less than that given as source for outbound DNS
 queries. Dnsmasq picks random ports as source for outbound queries:
-when this option is given, the ports used will always to larger
+when this option is given, the ports used will always be larger
 than that specified. Useful for systems behind firewalls. If not specified,
 defaults to 1024.
 .TP
@@ -296,7 +300,7 @@ option requires non-standard networking APIs and it is only available
 under Linux. On other platforms it falls-back to \fB--bind-interfaces\fP mode.
 .TP
 .B \-y, --localise-queries
-Return answers to DNS queries from /etc/hosts and \fB--interface-name\fP which depend on the interface over which the query was
+Return answers to DNS queries from /etc/hosts and \fB--interface-name\fP and \fB--dynamic-host\fP which depend on the interface over which the query was
 received. If a name has more than one address associated with
 it, and at least one of those addresses is on the same subnet as the
 interface to which the query was sent, then return only the
@@ -323,17 +327,17 @@ are re-written. So
 .B --alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0
 maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40
 .TP 
-.B \-B, --bogus-nxdomain=<ipaddr>
-Transform replies which contain the IP address given into "No such
-domain" replies. This is intended to counteract a devious move made by
+.B \-B, --bogus-nxdomain=<ipaddr>[/prefix]
+Transform replies which contain the specified address or subnet into "No such
+domain" replies. IPv4 and IPv6 are supported. This is intended to counteract a devious move made by
 Verisign in September 2003 when they started returning the address of
 an advertising web page in response to queries for unregistered names,
 instead of the correct NXDOMAIN response. This option tells dnsmasq to
 fake the correct response when it sees this behaviour. As at Sept 2003
 the IP address being returned by Verisign is 64.94.110.11
 .TP 
-.B --ignore-address=<ipaddr>
-Ignore replies to A-record queries which include the specified address
+.B --ignore-address=<ipaddr>[/prefix]
+Ignore replies to A or AAAA queries which include the specified address or subnet
 No error is generated, dnsmasq simply continues to listen for another reply. 
 This is useful to defeat blocking strategies which rely on quickly supplying a
 forged answer to a DNS request for certain domain, before the correct answer can arrive.
@@ -368,7 +372,10 @@ provides service at that name, rather than the default which is
 .TP 
 .B --enable-ubus[=<service-name>]
 Enable dnsmasq UBus interface. It sends notifications via UBus on
-DHCPACK and DHCPRELEASE events. Furthermore it offers metrics.
+DHCPACK and DHCPRELEASE events. Furthermore it offers metrics
+and allows configuration of Linux connection track mark based filtering.
+When DNS query filtering based on Linux connection track marks is enabled
+UBus notifications are generated for each resolved or filtered DNS query.
 Requires that dnsmasq has been built with UBus support. If the service
 name is given, dnsmasq provides service at that namespace, rather than
 the default which is
@@ -428,7 +435,7 @@ Tells dnsmasq to never forward A or AAAA queries for plain names, without dots
 or domain parts, to upstream nameservers. If the name is not known
 from /etc/hosts or DHCP then a "not found" answer is returned.
 .TP
-.B \-S, --local, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>]][@<source-ip>|<interface>[#<port>]]
+.B \-S, --local, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>]][@<interface>][@<source-ip>[#<port>]]
 Specify IP address of upstream servers directly. Setting this flag does
 not suppress reading of /etc/resolv.conf, use \fB--no-resolv\fP to do that. If one or more
 optional domains are given, that server is used only for those domains
@@ -454,13 +461,22 @@ repeated domain or ipaddr parts as required.
 More specific domains take precedence over less specific domains, so:
 .B --server=/google.com/1.2.3.4
 .B --server=/www.google.com/2.3.4.5
-will send queries for *.google.com to 1.2.3.4, except *www.google.com,
-which will go to 2.3.4.5
+will send queries for google.com and gmail.google.com to 1.2.3.4, but www.google.com
+will go to 2.3.4.5
+
+Matching of domains is normally done on complete labels, so /google.com/ matches google.com and www.google.com
+but NOT supergoogle.com. This can be overridden with a * at the start of a pattern only: /*google.com/
+will match google.com and www.google.com AND supergoogle.com. The non-wildcard form has priority, so
+if /google.com/ and /*google.com/ are both specified then google.com and www.google.com will match /google.com/
+and /*google.com/ will only match supergoogle.com.
+
+For historical reasons, the pattern /.google.com/ is equivalent to /google.com/ if you wish to match any subdomain
+of google.com but NOT google.com itself, use /*.google.com/
 
 The special server address '#' means, "use the standard servers", so
 .B --server=/google.com/1.2.3.4
 .B --server=/www.google.com/#
-will send queries for *.google.com to 1.2.3.4, except *www.google.com which will
+will send queries for google.com and its subdomains to 1.2.3.4, except www.google.com (and its subdomains) which will
 be forwarded as usual.
 
 Also permitted is a -S
@@ -489,7 +505,7 @@ source address specified but the port may be specified directly as
 part of the source address. Forcing queries to an interface is not
 implemented on all platforms supported by dnsmasq.
 .TP
-.B --rev-server=<ip-address>/<prefix-len>[,<ipaddr>][#<port>][@<source-ip>|<interface>[#<port>]]
+.B --rev-server=<ip-address>/<prefix-len>[,<ipaddr>][#<port>][@<interface>][@<source-ip>[#<port>]]
 This is functionally the same as 
 .B --server, 
 but provides some syntactic sugar to make specifying address-to-name queries easier. For example
@@ -507,7 +523,7 @@ To include multiple IP addresses for a single query, use
 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 \fB--server\fP, with
+domain specification works in the same way 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
@@ -533,6 +549,32 @@ These IP sets must already exist. See
 .BR ipset (8)
 for more details.
 .TP
+.B --connmark-allowlist-enable[=<mask>]
+Enables filtering of incoming DNS queries with associated Linux connection track marks
+according to individual allowlists configured via a series of \fB--connmark-allowlist\fP
+options. Disallowed queries are not forwarded; they are rejected with a REFUSED error code.
+DNS queries are only allowed if they do not have an associated Linux connection
+track mark, or if the queried domains match the configured DNS patterns for the
+associated Linux connection track mark. If no allowlist is configured for a
+Linux connection track mark, all DNS queries associated with that mark are rejected.
+If a mask is specified, Linux connection track marks are first bitwise ANDed
+with the given mask before being processed.
+.TP
+.B --connmark-allowlist=<connmark>[/<mask>][,<pattern>[/<pattern>...]]
+Configures the DNS patterns that are allowed in DNS queries associated with
+the given Linux connection track mark.
+If a mask is specified, Linux connection track marks are first bitwise ANDed
+with the given mask before they are compared to the given connection track mark.
+Patterns follow the syntax of DNS names, but additionally allow the wildcard
+character "*" to be used up to twice per label to match 0 or more characters
+within that label. Note that the wildcard never matches a dot (e.g., "*.example.com"
+matches "api.example.com" but not "api.us.example.com"). Patterns must be
+fully qualified, i.e., consist of at least two labels. The final label must not be
+fully numeric, and must not be the "local" pseudo-TLD. A pattern must end with at least
+two literal (non-wildcard) labels.
+Instead of a pattern, "*" can be specified to disable allowlist filtering
+for a given Linux connection track mark entirely.
+.TP
 .B \-m, --mx-host=<mx name>[[,<hostname>],<preference>]
 Return an MX record named <mx name> pointing to the given hostname (if
 given), or
@@ -591,6 +633,12 @@ If the time-to-live is given, it overrides the default, which is zero
 or the value of \fB--local-ttl\fP. The value is a positive integer and gives
 the time-to-live in seconds.
 .TP
+.B --dynamic-host=<name>,[IPv4-address],[IPv6-address],<interface>
+Add A, AAAA and PTR records to the DNS in the same subnet as the specified interface. The address is derived from the network part of each address associated with the interface, and the host part from the specified address. For example
+.B --dynamic-host=example.com,0.0.0.8,eth0
+will, when eth0 has the address 192.168.78.x and netmask 255.255.255.0 give the
+name example.com an A record for 192.168.78.8. The same principle applies to IPv6 addresses. Note that if an interface has more than one address, more than one A or AAAA record will be created. The TTL of the records is always zero, and any changes to interface addresses will be immediately reflected in them.
+.TP
 .B \-Y, --txt-record=<name>[[,<text>],<text>]
 Return a TXT DNS record. The value of TXT record is a set of strings,
 so  any number may be included, delimited by commas; use quotes to put
@@ -658,7 +706,8 @@ 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
-<ip address>,<ip address> or <ip address>/<netmask> in both forms of the option.
+<start address>,<end address> or <ip address>/<prefix-length> in both forms of the option. For IPv6 the start and end addresses
+must fall in the same /64 network, or prefix-length must be greater than or equal to 64 except that shorter prefix lengths than 64 are allowed only if non-sequential names are in use.
 .TP
 .B --dumpfile=<path/to/file>
 Specify the location of a pcap-format file which dnsmasq uses to dump copies of network packets for debugging purposes. If the file exists when dnsmasq starts, it is not deleted; new packets are added to the end.
@@ -702,7 +751,13 @@ will add the /24 and /96 subnets of the requestor for IPv4 and IPv6 requestors,
 will add 1.2.3.0/24 for IPv4 requestors and ::/0 for IPv6 requestors.
 .B --add-subnet=1.2.3.4/24,1.2.3.4/24
 will add 1.2.3.0/24 for both IPv4 and IPv6 requestors.
-
+.TP
+.B --umbrella[=deviceid:<deviceid>[,orgid:<orgid>]]
+Embeds the requestor's IP address in DNS queries forwarded upstream.
+If device id or organization id are specified, the information is
+included in the forwarded queries and may be able to be used in
+filtering policies and reporting. The order of the deviceid and orgid
+attributes is irrelevant, but must be separated by a comma.
 .TP
 .B \-c, --cache-size=<cachesize>
 Set the size of dnsmasq's cache. The default is 150 names. Setting the cache size to zero disables caching. Note: huge cache size impacts performance.
@@ -716,7 +771,8 @@ identical queries without forwarding them again.
 Set the maximum number of concurrent DNS queries. The default value is
 150, which should be fine for most setups. The only known situation
 where this needs to be increased is when using web-server log file
-resolvers, which can generate large numbers of concurrent queries.
+resolvers, which can generate large numbers of concurrent queries. This
+parameter actually controls the number of concurrent queries per server group, where a server group is the set of server(s) associated with a single domain. So if a domain has it's own server via --server=/example.com/1.2.3.4 and 1.2.3.4 is not responding, but queries for *.example.com cannot go elsewhere, then other queries will not be affected. On configurations with many such server groups and tight resources, this value may need to be reduced.
 .TP
 .B --dnssec
 Validate DNS replies and cache DNSSEC data. When forwarding DNS queries, dnsmasq requests the 
@@ -850,7 +906,7 @@ compiled in and the kernel must have conntrack support
 included and configured. This option cannot be combined with
 .B --query-port.
 .TP
-.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>|<mode>][,<netmask>[,<broadcast>]][,<lease time>]
+.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>|<mode>[,<netmask>[,<broadcast>]]][,<lease time>]
 .TP
 .B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-IPv6addr>[,<end-IPv6addr>|constructor:<interface>][,<mode>][,<prefix-len>][,<lease time>]
 
@@ -860,7 +916,7 @@ in
 .B --dhcp-host
 options. If the lease time is given, then leases
 will be given for that length of time. The lease time is in seconds,
-or minutes (eg 45m) or hours (eg 1h) or "infinite". If not given,
+or minutes (eg 45m) or hours (eg 1h) or days (2d) or weeks (1w) or "infinite". If not given,
 the default lease time is one hour for IPv4 and one day for IPv6. The
 minimum lease time is two minutes. For IPv6 ranges, the lease time
 maybe "deprecated"; this sets the preferred lifetime sent in a DHCP
@@ -1045,6 +1101,19 @@ option, but aliases are possible by using CNAMEs. (See
 .B --cname
 ).
 
+More than one
+.B --dhcp-host
+can be associated (by name, hardware address or UID) with a host. Which one is used
+(and therefore which address is allocated by DHCP and appears in the DNS) depends
+on the subnet on which the host last obtained a DHCP lease:
+the
+.B --dhcp-host
+with an address within the subnet is used. If more than one address is within the subnet,
+the result is undefined. A corollary to this is that the name associated with a host using
+.B --dhcp-host
+does not appear in the DNS until the host obtains a DHCP lease.
+
+
 The special keyword "ignore"
 tells dnsmasq to never offer a DHCP lease to a machine. The machine
 can be specified by hardware address, client ID or hostname, for
@@ -1097,7 +1166,7 @@ has both wired and wireless interfaces.
 .TP
 .B --dhcp-hostsfile=<path>
 Read DHCP host information from the specified file. If a directory
-is given, then read all the files contained in that directory. The file contains 
+is given, then read all the files contained in that directory in alphabetical order. The file contains 
 information about one host per line. The format of a line is the same
 as text to the right of '=' in \fB--dhcp-host\fP. The advantage of storing DHCP host information
 in this file is that it can be changed without re-starting dnsmasq:
@@ -1105,7 +1174,7 @@ the file will be re-read when dnsmasq receives SIGHUP.
 .TP
 .B --dhcp-optsfile=<path>
 Read DHCP option information from the specified file.  If a directory
-is given, then read all the files contained in that directory. The advantage of 
+is given, then read all the files contained in that directory in alphabetical order. The advantage of 
 using this option is the same as for \fB--dhcp-hostsfile\fP: the
 \fB--dhcp-optsfile\fP will be re-read when dnsmasq receives SIGHUP. Note that
 it is possible to encode the information in a
@@ -1120,7 +1189,8 @@ directory, and not an individual file. Changed or new files within
 the directory are read automatically, without the need to send SIGHUP.
 If a file is deleted or changed after it has been read by dnsmasq, then the
 host record it contained will remain until dnsmasq receives a SIGHUP, or 
-is restarted; ie host records are only added dynamically.
+is restarted; ie host records are only added dynamically. The order in which the
+files in a directory are read is not defined.
 .TP
 .B --dhcp-optsdir=<path>
 This is equivalent to \fB--dhcp-optsfile\fP, with the differences noted for \fB--dhcp-hostsdir\fP.
@@ -1365,6 +1435,12 @@ Any number of set: and tag: forms may appear, in any order.
 tag set by another
 .B --tag-if,
 the line which sets the tag must precede the one which tests it.
+
+As an extension, the tag:<tag> clauses support limited wildcard matching,
+similar to the matching in the \fB--interface\fP directive.  This allows, for
+example, using \fB--tag-if=set:ppp,tag:ppp*\fP to set the tag 'ppp' for all requests
+received on any matching interface (ppp0, ppp1, etc).  This can be used in conjunction
+with the tag:!<tag> format meaning that no tag matching the wildcard may be set.
 .TP
 .B \-J, --dhcp-ignore=tag:<tag>[,tag:<tag>]
 When all the given tags appear in the tag set ignore the host and do
@@ -1436,7 +1512,7 @@ functions when supported by a suitable DHCP server.
 This specifies a boot option which may appear in a PXE boot menu. <CSA> is
 client system type, only services of the correct type will appear in a
 menu. The known types are x86PC, PC98, IA64_EFI, Alpha, Arc_x86,
-Intel_Lean_Client, IA32_EFI,  X86-64_EFI, Xscale_EFI, BC_EFI, ARM32_EFI and ARM64_EFI; an
+Intel_Lean_Client, IA32_EFI,  x86-64_EFI, Xscale_EFI, BC_EFI, ARM32_EFI and ARM64_EFI; an
 integer may be used for other types. The
 parameter after the menu text may be a file name, in which case dnsmasq acts as a
 boot server and directs the PXE client to download the file by TFTP,
@@ -1495,7 +1571,6 @@ instance
 will enable dnsmasq to also provide proxy PXE service to those PXE clients with
 .I HW-Client
 in as their identifier.
->>>>>>> 907def3... pxe: support pxe clients with custom vendor-class
 .TP  
 .B \-X, --dhcp-lease-max=<number>
 Limits dnsmasq to the specified maximum number of DHCP leases. The
@@ -1546,10 +1621,11 @@ tried. This flag disables this check. Use with caution.
 Extra logging for DHCP: log all the options sent to DHCP clients and
 the tags used to determine them.
 .TP
-.B --quiet-dhcp, --quiet-dhcp6, --quiet-ra
+.B --quiet-dhcp, --quiet-dhcp6, --quiet-ra, --quiet-tftp
 Suppress logging of the routine operation of these protocols. Errors and
-problems will still be logged. \fB--quiet-dhcp\fP and quiet-dhcp6 are
-over-ridden by \fB--log-dhcp\fP.
+problems will still be logged. \fB--quiet-tftp\fP does not consider file not
+found to be an error. \fB--quiet-dhcp\fP and quiet-dhcp6 are over-ridden by
+\fB--log-dhcp\fP.
 .TP
 .B \-l, --dhcp-leasefile=<path>
 Use the specified file to store DHCP lease information.
@@ -2351,6 +2427,10 @@ following data is used to populate the authoritative zone.
 .B --mx-host, --srv-host, --dns-rr, --txt-record, --naptr-record, --caa-record,
 as long as the record names are in the authoritative domain.
 .PP
+.B --synth-domain
+as long as the domain is in the authoritative zone and, for
+reverse (PTR) queries, the address is in the relevant subnet.
+.PP
 .B --cname
 as long as the record name is in  the authoritative domain. If the
 target of the CNAME is unqualified, then it  is qualified with the
@@ -2367,6 +2447,8 @@ IPv4 and IPv6 addresses from /etc/hosts (and
 .B --host-record
 and 
 .B --interface-name
+and
+.B ---dynamic-host
 provided the address falls into one of the subnets specified in the
 .B --auth-zone.
 .PP
index 6e80188..9cd48ee 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -1,7 +1,8 @@
 # German translations for dnsmasq package.
 #
 # This revised version is (C) Copyright by
-# Matthias Andree <matthias.andree@gmx.de>, 2010.
+# Matthias Andree <matthias.andree@gmx.de>, 2010 - 2021.
+# Conrad Kostecki <ck@conrad-kostecki.de>, 2014 - 2020.
 # It is subject to the GNU General Public License v2,
 # or at your option, any later version.
 #
 # Simon Kelley <simon@thekelleys.org.uk>, 2005.
 msgid ""
 msgstr ""
-"Project-Id-Version: dnsmasq 2.81\n"
+"Project-Id-Version: dnsmasq 2.85rc2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-06-18 12:24+0100\n"
-"PO-Revision-Date: 2020-03-08 20:25+0100\n"
-"Last-Translator: Conrad Kostecki <conrad@kostecki.com>\n"
+"POT-Creation-Date: 2021-03-20 00:00+0000\n"
+"PO-Revision-Date: 2021-03-27 15:30+0100\n"
+"Last-Translator: Matthias Andree <matthias.andree@gmx.de>\n"
 "Language-Team: German <de@li.org>\n"
 "Language: de\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.3\n"
-"X-Poedit-SourceCharset: UTF-8\n"
 
-#: cache.c:559
+#: cache.c:572
 msgid "Internal error in cache."
 msgstr "Interner Fehler im Cache."
 
-#: cache.c:1081
+#: cache.c:1094
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr "Fehler beim Laden der Namen von %s: %s"
 
-#: cache.c:1103 dhcp.c:927
+#: cache.c:1116 dhcp.c:931
 #, c-format
 msgid "bad address at %s line %d"
 msgstr "Fehlerhafte Adresse in %s Zeile %d"
 
-#: cache.c:1156 dhcp.c:943
+#: cache.c:1169 dhcp.c:947
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "Fehlerhafter Name in %s Zeile %d"
 
-#: cache.c:1167 dhcp.c:1018
+#: cache.c:1180 dhcp.c:1022
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "%s gelesen - %d Adressen"
 
-#: cache.c:1283
+#: cache.c:1296
 msgid "cleared cache"
 msgstr "Cache geleert"
 
-#: cache.c:1345
+#: cache.c:1358
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr "Keine IPv4-Adresse für %s gefunden"
 
-#: cache.c:1391
+#: cache.c:1404
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr "%s ist ein CNAME, weise es der DHCP-Lease von %s nicht zu"
 
-#: cache.c:1415
+#: cache.c:1428
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "Name %s wurde dem DHCP-Lease von %s nicht zugewiesen, da der Name in %s bereits mit Adresse %s existiert"
 
-#: cache.c:1663
+#: cache.c:1674
 #, c-format
 msgid "time %lu"
 msgstr "Zeit %lu"
 
-#: cache.c:1664
+#: cache.c:1675
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "Cache Größe %d, %d/%d Cache-Einfügungen verwendeten nicht abgelaufene Cache-Einträge wieder."
 
-#: cache.c:1666
+#: cache.c:1677
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
-msgstr "%u weitergeleitete Anfragen, %u lokal beantwortete Anfragen"
+msgstr "weitergeleitete Anfragen %u, lokal beantwortete Anfragen %u"
 
-#: cache.c:1669
+#: cache.c:1680
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr "Anfragen nach autoritativen Zonen %u"
 
-#: cache.c:1694
+#: cache.c:1702
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
-msgstr "Server %s#%d: %u Anfragen gesendet, %u erneut versucht oder fehlgeschlagen"
+msgstr "Server %s#%d: Anfragen gesendet %u, erneut versucht oder fehlgeschlagen %u"
 
-#: util.c:47
+#: util.c:51
 #, c-format
 msgid "failed to seed the random number generator: %s"
 msgstr "Konnte den Zufallszahlengenerator nicht initialisieren: %s"
 
-#: util.c:224
+#: util.c:228
 msgid "failed to allocate memory"
 msgstr "Konnte Speicher nicht belegen"
 
-#: util.c:281 option.c:641
+#: util.c:285 option.c:665
 msgid "could not get memory"
 msgstr "Speicher nicht verfügbar"
 
-#: util.c:302
+#: util.c:306
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr "Konnte Pipe nicht erzeugen: %s"
 
-#: util.c:310
+#: util.c:314
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr "Konnte %d Bytes nicht belegen"
 
 # @Simon: not perfect but I cannot get nearer right now.
-#: util.c:506
+#: util.c:520
 #, c-format
 msgid "infinite"
 msgstr "unendlich"
 
-#: option.c:358
+#: util.c:808
+#, c-format
+msgid "failed to find kernel version: %s"
+msgstr "konnte Kernelversion nicht finden: %s"
+
+#: option.c:372
 msgid "Specify local address(es) to listen on."
 msgstr "Lokale abzuhörende Adresse(n) angeben."
 
-#: option.c:359
+#: option.c:373
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "IP-Adresse für alle Hosts in angegebenen Domänen festlegen."
 
-# FIXME: the English test is not to the point. Just use a shortened description
-# from the manpage instead. -- MA
-#: option.c:360
+#: option.c:374
 msgid "Fake reverse lookups for RFC1918 private address ranges."
-msgstr "Für private Adressbereiche nach RFC1918 \"keine solche Domain\" liefern."
+msgstr "Rückwärtsauflösungen für private Adressbereiche nach RFC1918 falsch erfinden."
 
-#: option.c:361
+#: option.c:375
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Diese IP-Adresse als NXDOMAIN interpretieren (wehrt \"Suchhilfen\" ab)."
 
-#: option.c:362
+#: option.c:376
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Größe des Caches (Zahl der Einträge) festlegen (Voreinstellung: %s)."
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Konfigurationsdatei festlegen (Voreinstellung: %s)."
 
-#: option.c:364
+#: option.c:378
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "NICHT in den Hintergrund gehen: Betrieb im Debug-Modus."
 
-#: option.c:365
+#: option.c:379
 msgid "Do NOT forward queries with no domain part."
 msgstr "Anfragen ohne Domänen-Teil NICHT weiterschicken."
 
-#: option.c:366
+#: option.c:380
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Für lokale Einträge MX-Einträge liefern, die auf sich selbst zeigen."
 
-#: option.c:367
+#: option.c:381
 msgid "Expand simple names in /etc/hosts with domain-suffix."
-msgstr "Erweitere einfache Namen in /etc/hosts mit der Domänen-Endung."
+msgstr "Einfache Namen in /etc/hosts um Domänen-Endung erweitern."
 
-#: option.c:368
+#: option.c:382
 msgid "Don't forward spurious DNS requests from Windows hosts."
-msgstr "'unechte' DNS-Anfragen von Windows-Rechnern nicht weiterleiten."
+msgstr "Unberechtigte DNS-Anfragen von Windows-Rechnern nicht weiterleiten."
 
-# @Simon: I'm a bit unsure about "spurious"
-#: option.c:369
+#: option.c:383
 msgid "Enable DHCP in the range given with lease duration."
-msgstr "DHCP für angegebenen Bereich und Dauer einschalten."
+msgstr "DHCP für angegebenen Bereich und Lease-Dauer einschalten."
 
-#: option.c:370
+#: option.c:384
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Nach dem Start in diese Benutzergruppe wechseln (Voreinstellung %s)."
 
-#: option.c:371
+#: option.c:385
 msgid "Set address or hostname for a specified machine."
 msgstr "Adresse oder Hostnamen für einen angegebenen Computer setzen."
 
-#: option.c:372
+#: option.c:386
 msgid "Read DHCP host specs from file."
 msgstr "DHCP-Host-Angaben aus Datei lesen."
 
-#: option.c:373
+#: option.c:387
 msgid "Read DHCP option specs from file."
 msgstr "DHCP-Optionen aus Datei lesen."
 
-#: option.c:374
+#: option.c:388
 msgid "Read DHCP host specs from a directory."
 msgstr "DHCP-Host-Angaben aus einem Verzeichnis lesen."
 
-#: option.c:375
+#: option.c:389
 msgid "Read DHCP options from a directory."
 msgstr "DHCP-Optionen aus einem Verzeichnis lesen."
 
-#: option.c:376
+#: option.c:390
 msgid "Evaluate conditional tag expression."
 msgstr "Auswertung eines Ausdrucks bedingter Marken."
 
-#: option.c:377
+#: option.c:391
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "%s-Datei NICHT laden."
 
-#: option.c:378
+#: option.c:392
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Hosts-Datei festlegen, die zusätzlich zu %s gelesen wird."
 
-#: option.c:379
+#: option.c:393
 msgid "Read hosts files from a directory."
 msgstr "DHCP-Host-Dateien aus einem Verzeichnis lesen."
 
-#: option.c:380
+#: option.c:394
 msgid "Specify interface(s) to listen on."
 msgstr "Schnittstelle(n) zum Empfang festlegen."
 
-#: option.c:381
+#: option.c:395
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Schnittstelle(n) festlegen, die NICHT empfangen sollen."
 
-#: option.c:382
+#: option.c:396
 msgid "Map DHCP user class to tag."
 msgstr "DHCP-Benutzerklasse auf Marke abbilden."
 
-#: option.c:383
+#: option.c:397
 msgid "Map RFC3046 circuit-id to tag."
 msgstr "RFC3046 \"circuit-id\" auf Marke abbilden."
 
-#: option.c:384
+#: option.c:398
 msgid "Map RFC3046 remote-id to tag."
 msgstr "RFC3046 \"remote-id\" auf Marke abbilden."
 
-#: option.c:385
+#: option.c:399
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr "RFC3993 \"subscriber-id\" auf Marke abbilden."
 
-#: option.c:386
+#: option.c:400
+msgid "Specify vendor class to match for PXE requests."
+msgstr "Herstellerklasse für Vergleich von PXE-Anforderungen angeben"
+
+#: option.c:401
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Kein DHCP für Hosts mit gesetzter Marke verwenden."
 
-#: option.c:387
+#: option.c:402
 msgid "Force broadcast replies for hosts with tag set."
-msgstr "Rundsendung für Hosts mit gesetzter Marke erzwingen."
+msgstr "Antwort per Broadcast für Hosts mit gesetzter Marke erzwingen."
 
-#: option.c:388
+#: option.c:403
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "NICHT in den Hintergrund wechseln, NICHT im Debug-Modus laufen."
 
-#: option.c:389
+#: option.c:404
 msgid "Assume we are the only DHCP server on the local network."
-msgstr "Voraussetzen, dass wir der einzige DHCP-Server im lokalen Netz sind."
+msgstr "Unterstellen, dass wir der einzige DHCP-Server im lokalen Netz sind."
 
-#: option.c:390
+#: option.c:405
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Festlegen, wo DHCP-Leases gespeichert werden (Voreinstellung %s)."
 
-#: option.c:391
+#: option.c:406
 msgid "Return MX records for local hosts."
 msgstr "MX-Einträge für lokale Hosts liefern."
 
-#: option.c:392
+#: option.c:407
 msgid "Specify an MX record."
 msgstr "Einen MX-Eintrag festlegen."
 
-#: option.c:393
+#: option.c:408
 msgid "Specify BOOTP options to DHCP server."
 msgstr "BOOTP-Optionen für DHCP-Server festlegen."
 
-#: option.c:394
+#: option.c:409
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "%s-Datei NICHT abfragen, nur bei SIGHUP neu laden."
 
-#: option.c:395
+#: option.c:410
 msgid "Do NOT cache failed search results."
 msgstr "Fehlerhafte Suchergebnisse NICHT zwischenspeichern."
 
-#: option.c:396
+#: option.c:411
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Namensserver streng in der in %s angegebenen Reihenfolge verwenden."
 
-#: option.c:397
+#: option.c:412
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Optionen festlegen, die an DHCP-Klienten gesendet werden."
 
-#: option.c:398
+#: option.c:413
 msgid "DHCP option sent even if the client does not request it."
 msgstr "DHCP-Option, die selbst ohne Klientenanfrage gesendet wird."
 
-#: option.c:399
+#: option.c:414
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
-msgstr "Port zum Abhören der DNS-Anfragen festlegen (53 voreingestellt)."
+msgstr "Port zum Empfangen der DNS-Anfragen festlegen (53 voreingestellt)."
 
-#: option.c:400
+#: option.c:415
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Maximale unterstützte UDP-Paketgröße für EDNS.0 (Voreinstellung %s)."
 
-#: option.c:401
+#: option.c:416
 msgid "Log DNS queries."
 msgstr "DNS-Anfragen protokollieren."
 
-#: option.c:402
+#: option.c:417
 msgid "Force the originating port for upstream DNS queries."
-msgstr "Ausgehenden Port erzwingen für DNS-Anfragen an vorgelagerte Server."
+msgstr "Ausgehenden Port für DNS-Anfragen an vorgelagerte Server erzwingen."
 
-#: option.c:403
+#: option.c:418
 msgid "Do NOT read resolv.conf."
 msgstr "Die resolv.conf NICHT lesen."
 
-#: option.c:404
+#: option.c:419
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Pfad zu resolv.conf festlegen (%s voreingestellt)."
 
-#: option.c:405
+#: option.c:420
 msgid "Specify path to file with server= options"
-msgstr "Dateipfad mit der Option server= angeben"
+msgstr "Pfad für Datei mit server=-Optionen angeben"
 
-#: option.c:406
+#: option.c:421
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Adresse(n) vorgelagerter Server festlegen, optional mit Domänen."
 
-#: option.c:407
+#: option.c:422
 msgid "Specify address of upstream servers for reverse address queries"
-msgstr "Adresse(n) vorgelagerter Server festlegen, für reverse Adressanfragen"
+msgstr "Adresse(n) vorgelagerter Server festlegen, für Rückwärtsauflösung"
 
-#: option.c:408
+#: option.c:423
 msgid "Never forward queries to specified domains."
 msgstr "Anfragen für angegebene Domänen niemals weiterleiten."
 
-#: option.c:409
+#: option.c:424
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Domäne festlegen, die für DHCP-Leases zugewiesen wird."
 
-#: option.c:410
+#: option.c:425
 msgid "Specify default target in an MX record."
 msgstr "Voreingestelltes Ziel für MX-Einträge festlegen."
 
-#: option.c:411
+#: option.c:426
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Gültigkeitsdauer für Antworten aus /etc/hosts festlegen."
 
-#: option.c:412
+#: option.c:427
 msgid "Specify time-to-live in seconds for negative caching."
-msgstr "Gültigkeitsdauer in Sekunden für Caching negativer Ergebnisse festlegen."
+msgstr "Gültigkeitsdauer in Sekunden für Zwischenspeicher negativer Ergebnisse festlegen."
 
-#: option.c:413
+#: option.c:428
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Gültigkeitsdauer in Sekunden für Caching negativer Ergebnisse festlegen."
 
-#: option.c:414
+#: option.c:429
 msgid "Specify time-to-live ceiling for cache."
-msgstr "Spezifiziere time-to-live ceiling für Cache."
+msgstr "Spezifiziere obere Gültigkeitsdauergrenze für Zwischenspeicher."
 
-#: option.c:415
+#: option.c:430
 msgid "Specify time-to-live floor for cache."
-msgstr "Spezifiziere time-to-live floor für Cache."
+msgstr "Spezifiziere untere Gültigkeitsdauergrenze für Zwischenspeicher."
 
-#: option.c:416
+#: option.c:431
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Nach dem Start diese Benutzerrechte annehmen (%s voreingestellt)."
 
-#: option.c:417
+#: option.c:432
 msgid "Map DHCP vendor class to tag."
 msgstr "DHCP-\"vendor class\" auf Marke abbilden."
 
-#: option.c:418
+#: option.c:433
 msgid "Display dnsmasq version and copyright information."
 msgstr "DNSMasq-Version und Urheberrecht anzeigen."
 
-#: option.c:419
+#: option.c:434
 msgid "Translate IPv4 addresses from upstream servers."
-msgstr "IPv4-Adressen von vorgelagerten Servern übersetzen."
+msgstr "IPv4-Adressen von vorgelagerten Servern umsetzen."
 
-#: option.c:420
+#: option.c:435
 msgid "Specify a SRV record."
 msgstr "SRV-Eintrag festlegen."
 
-#: option.c:421
+#: option.c:436
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr "Diese Hilfe anzeigen. Benutzen Sie --help dhcp oder --help dhcp6 für bekannte DHCP-Optionen."
 
-#: option.c:422
+#: option.c:437
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
-msgstr "Dateipfad für Prozesskennung (PID) festlegen (Voreinstellung: %s)."
+msgstr "Pfad für Prozesskennungsdatei (PID) festlegen (Voreinstellung: %s)."
 
-#: option.c:423
+#: option.c:438
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Höchstzahl der DHCP-Leases festlegen (%s voreingestellt)."
 
-#: option.c:424
+#: option.c:439
 msgid "Answer DNS queries based on the interface a query was sent to."
-msgstr "DNS-Anfragen abhängig der Emfpangsschnittstelle beantworten."
+msgstr "DNS-Anfragen abhängig der Empfangsschnittstelle beantworten."
 
-#: option.c:425
+#: option.c:440
 msgid "Specify TXT DNS record."
 msgstr "DNS-TXT-Eintrag festlegen."
 
-#: option.c:426
+#: option.c:441
 msgid "Specify PTR DNS record."
 msgstr "DNS-PTR-Eintrag festlegen."
 
-#: option.c:427
+#: option.c:442
 msgid "Give DNS name to IPv4 address of interface."
-msgstr "Schnittstellennamen zur IPv4-Adresse des Interfaces auflösen."
+msgstr "Schnittstellennamen zur IPv4-Adresse der Schnittstelle auflösen."
 
-#: option.c:428
+#: option.c:443
 msgid "Bind only to interfaces in use."
 msgstr "Nur an verwendete Schnittstellen binden."
 
-#: option.c:429
+#: option.c:444
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Statische DHCP-Host-Information aus %s lesen."
 
-#: option.c:430
+#: option.c:445
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "DBus-Schnittstelle zum Festlegen vorgelagerter Server usw. festlegen."
 
-#: option.c:431
+#: option.c:446
 msgid "Enable the UBus interface."
 msgstr "UBus-Schnittstelle aktivieren."
 
-#: option.c:432
+#: option.c:447
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "Auf dieser Schnittstelle kein DHCP anbieten, sondern nur DNS."
 
-#: option.c:433
+#: option.c:448
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Dynamische Adressbelegung für bootp einschalten."
 
-#: option.c:434
+#: option.c:449
 msgid "Map MAC address (with wildcards) to option set."
-msgstr "MAC-Adresse (mit Jokerzeichen) auf Netzmarke abbilden."
+msgstr "MAC-Adresse (mit Jokerzeichen) auf Optionenmenge abbilden."
 
-#: option.c:435
+#: option.c:450
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr "DHCP-Anfragen von Alias-Schnittstellen für die Hauptschnittstelle beantworten."
 
-#: option.c:436
+#: option.c:451
 msgid "Specify extra networks sharing a broadcast domain for DHCP"
 msgstr "Geben Sie zusätzliche Netzwerke an, die eine Broadcast-Domäne für DHCP gemeinsam nutzen"
 
-#: option.c:437
+#: option.c:452
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr "ICMP-Echo-Adressprüfung im DHCP-Server abschalten."
 
-#: option.c:438
+#: option.c:453
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr "Skript, das bei Erzeugung/Löschung einer DHCP-Lease laufen soll."
 
-#: option.c:439
+#: option.c:454
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr "Lua-Skript, welches bei Erzeugung/Löschung eines DHCP-Leases laufen soll."
 
-#: option.c:440
+#: option.c:455
 msgid "Run lease-change scripts as this user."
 msgstr "Lease-Änderungs-Skript mit den Rechten dieses Nutzers ausführen."
 
-#: option.c:441
+#: option.c:456
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr "Rufe dhcp-script mit Änderungen an der lokalen ARP-Tabelle auf."
 
-#: option.c:442
+#: option.c:457
 msgid "Read configuration from all the files in this directory."
 msgstr "Konfiguration aus allen Dateien in diesem Verzeichnis lesen."
 
-#: option.c:443
+#: option.c:458
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Für diese Syslog-Anlage oder in Datei loggen (Voreinstellung DAEMON)."
 
-#: option.c:444
+#: option.c:459
 msgid "Do not use leasefile."
 msgstr "Keine Lease-Datei benützen."
 
-#: option.c:445
+#: option.c:460
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Höchstzahl nebenläufiger DNS-Anfragen (%s voreingestellt)."
 
-#: option.c:446
+#: option.c:461
 #, c-format
 msgid "Clear DNS cache when reloading %s."
-msgstr "DNS-Cache beim Neuladen von %s löschen."
+msgstr "DNS-Zwischenspeicher beim Neuladen von %s löschen."
 
-#: option.c:447
+#: option.c:462
 msgid "Ignore hostnames provided by DHCP clients."
-msgstr "Von DHCP-Clients gelieferte Hostnamen ignorieren."
+msgstr "Von DHCP-Klienten gelieferte Hostnamen ignorieren."
 
-#: option.c:448
+#: option.c:463
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
-msgstr "Dateinamen und Server-Datenfehler für zusätzliche DHCP-Optionen NICHT wiederverwenden."
+msgstr "Dateinamen und Server-Datenfelder NICHT für zusätzliche DHCP-Optionen wiederverwenden."
 
-#: option.c:449
+#: option.c:464
 msgid "Enable integrated read-only TFTP server."
-msgstr "Eingebauten Nur-Lese-TFTP-Server einschalten."
+msgstr "Eingebauten schreibgeschützten TFTP-Server einschalten."
 
-#: option.c:450
+#: option.c:465
 msgid "Export files by TFTP only from the specified subtree."
 msgstr "Nur vom festgelegten Unterbaum Dateien per TFTP exportieren."
 
-#: option.c:451
+#: option.c:466
 msgid "Add client IP or hardware address to tftp-root."
 msgstr "IP-Adresse oder Hardware-Adresse des Klienten an tftp-root anhängen."
 
-#: option.c:452
+#: option.c:467
 msgid "Allow access only to files owned by the user running dnsmasq."
-msgstr "Zugriff nur auf Dateien gestatten, die dem dnsmasq aufrufenden Benutzer gehören."
+msgstr "Zugriff nur auf Dateien gestatten, die dem dnsmasq betreibenden Benutzer gehören."
 
-#: option.c:453
+#: option.c:468
 msgid "Do not terminate the service if TFTP directories are inaccessible."
-msgstr "Der Dienst sollte nicht beendet werden, wenn die TFTP-Verzeichnisse nicht zugreifbar sind."
+msgstr "Den Dienst nicht beenden, wenn die TFTP-Verzeichnisse unerreichbar sind."
 
-#: option.c:454
+#: option.c:469
 #, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Maximale Anzahl gleichzeitiger TFTP-Übertragungen (%s voreingestellt)."
 
-#: option.c:455
+#: option.c:470
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Maximale MTU für TFTP-Übertragungen erreicht."
 
-#: option.c:456
+#: option.c:471
 msgid "Disable the TFTP blocksize extension."
 msgstr "TFTP-Blockgrößen-Erweiterung abschalten."
 
-#: option.c:457
+#: option.c:472
 msgid "Convert TFTP filenames to lowercase"
-msgstr "Konvertiere TFTP Dateinamen in Kleinschreibung"
+msgstr "TFTP-Dateinamen in Kleinschreibung umsetzen"
 
-#: option.c:458
+#: option.c:473
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr "Bereich für vorübergehende Ports für TFTP-Übertragungen."
 
-#: option.c:459
+#: option.c:474
 msgid "Use only one port for TFTP server."
 msgstr "Bitte nur einen Port für den TFTP-Server nutzen."
 
-#: option.c:460
+#: option.c:475
 msgid "Extra logging for DHCP."
 msgstr "Erweiterte DHCP-Protokollierung."
 
-#: option.c:461
+#: option.c:476
 msgid "Enable async. logging; optionally set queue length."
 msgstr "Asynchrone Protokollierung einschalten, opt. Warteschlangenlänge festlegen."
 
-#: option.c:462
+#: option.c:477
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr "DNS-Rebinding unterbinden, private IP-Bereiche bei der Auflösung ausfiltern."
 
-#: option.c:463
+#: option.c:478
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr "Auflösung zu 127.0.0.0/8 erlauben, für RBL-Server."
 
-#: option.c:464
+#: option.c:479
 msgid "Inhibit DNS-rebind protection on this domain."
-msgstr "DNS-Rebind-Schutz für diese Domäne sperren."
+msgstr "DNS-Rebind-Schutz für diese Domäne aufheben."
 
-#: option.c:465
+#: option.c:480
 msgid "Always perform DNS queries to all servers."
 msgstr "DNS-Anfragen immer an alle Server weiterleiten."
 
-#: option.c:466
+#: option.c:481
 msgid "Set tag if client includes matching option in request."
 msgstr "Marke setzen, wenn Klient eine entsprechende Option anfragt."
 
-#: option.c:467
+#: option.c:482
 msgid "Set tag if client provides given name."
 msgstr "Setzt das Tag, wenn der Client diesen Namen anbietet."
 
-#: option.c:468
+#: option.c:483
 msgid "Use alternative ports for DHCP."
 msgstr "Alternative Ports für DHCP verwenden."
 
-#: option.c:469
+#: option.c:484
 msgid "Specify NAPTR DNS record."
 msgstr "DNS-NAPTR-Eintrag festlegen."
 
-#: option.c:470
+#: option.c:485
 msgid "Specify lowest port available for DNS query transmission."
 msgstr "Niedrigsten verfügbaren Port für Übertragung von DNS-Anfragen festlegen."
 
-#: option.c:471
+#: option.c:486
 msgid "Specify highest port available for DNS query transmission."
 msgstr "Höchsten verfügbaren Port für Übertragung von DNS-Anfragen festlegen."
 
-#: option.c:472
+#: option.c:487
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr "Für DHCP-Klienten nur vollständig bestimmte Domänennamen benutzen."
 
 # FIXME: probably typo in original message. -- MA
-#: option.c:473
+#: option.c:488
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr "Generiere Hostnamen auf Basis der MAC-Adresse für namenlose Klienten."
 
-#: option.c:474
+#: option.c:489
 msgid "Use these DHCP relays as full proxies."
 msgstr "Diese DHCP-Relais als vollwertige Proxies verwenden."
 
-#: option.c:475
+#: option.c:490
 msgid "Relay DHCP requests to a remote server"
-msgstr "Leute DHCP Anfragen an entfernten Server weiter"
+msgstr "Leite DHCP-Anfragen an entfernten Server weiter"
 
-#: option.c:476
+#: option.c:491
 msgid "Specify alias name for LOCAL DNS name."
 msgstr "Alias für LOKALEN DNS-Namen festlegen."
 
-#: option.c:477
+#: option.c:492
 msgid "Prompt to send to PXE clients."
 msgstr "Aufforderung, die an PXE-Klienten geschickt wird."
 
-#: option.c:478
+#: option.c:493
 msgid "Boot service for PXE menu."
 msgstr "Boot-Dienst für PXE-Menü."
 
-#: option.c:479
+#: option.c:494
 msgid "Check configuration syntax."
 msgstr "Konfigurationssyntax prüfen."
 
-#: option.c:480
+#: option.c:495
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr "Anfragende MAC-Adresse in die weiterleitende DNS-Anfrage einfügen."
 
-#: option.c:481
+#: option.c:496
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr "Füge spezifiziertes IP-Subnetz an weitergeleiteten DNS-Anfragen hinzu."
 
-#: option.c:482
+#: option.c:497
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Füge Klient Identifikationan weitergeleiteten DNS-Anfragen hinzu."
 
-#: option.c:483
+# This is a rather liberal translation to convey the purpose.
+# something along "authorize upstream nameservers to validate DNSSEC [for us]"
+#: option.c:498
 msgid "Proxy DNSSEC validation results from upstream nameservers."
-msgstr "Proxy-DNSSEC-Validierung-Ergebnisse von Upstream-Namensservern."
+msgstr "Vorgelagerte Namensserver für DNSSEC-Validierung ermächtigen."
 
-#: option.c:484
+#: option.c:499
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
-msgstr "Versuche sequenzielle IP-Adressen an DHCP-Klienten zu vergeben."
+msgstr "Versuche, sequenzielle IP-Adressen an DHCP-Klienten zu vergeben."
 
-#: option.c:485
+#: option.c:500
 msgid "Ignore client identifier option sent by DHCP clients."
 msgstr "Ignorieren Sie die von DHCP-Clients gesendete Client-ID-Option."
 
-#: option.c:486
+#: option.c:501
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr "Kopiere \"connection-track mark\" von Anfragen nach Upstream-Verbindungen."
 
-#: option.c:487
+#: option.c:502
 msgid "Allow DHCP clients to do their own DDNS updates."
-msgstr "Erlaube DHCP-Klienten ihre eigenen DDNS-Updates durchzuführen."
+msgstr "Erlaube DHCP-Klienten, ihre eigenen DDNS-Updates durchzuführen."
 
-#: option.c:488
+#: option.c:503
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr "Sende \"Router-Advertisments\" für Netzwerkschnittstellen, welche DHCPv6 nutzen"
 
-#: option.c:489
+#: option.c:504
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr "Spezifiziere DUID_EN-type DHCPv6 Server DUID"
 
-#: option.c:490
+#: option.c:505
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Spezifiziere Host (A/AAAA und PTR) Einträge"
 
-#: option.c:491
+#: option.c:506
+msgid "Specify host record in interface subnet"
+msgstr "Host-Eintrag für das Unternetzwerk der Schnittstelle angeben"
+
+#: option.c:507
 msgid "Specify certification authority authorization record"
-msgstr "Geben Sie den Autorisierungsdatensatz der Zertifizierungsstelle an"
+msgstr "Autorisierungsdatensatz der Zertifizierungsstelle angeben"
 
-#: option.c:492
+#: option.c:508
 msgid "Specify arbitrary DNS resource record"
 msgstr "Spezifiziere einen beliebiegen DNS Eintrag"
 
-#: option.c:493
+#: option.c:509
 msgid "Bind to interfaces in use - check for new interfaces"
-msgstr "Bindung zu Schnittstellen in Benutzung - prüfe auf neue Schnittstellen"
+msgstr "Bindung an Schnittstellen in Benutzung - prüfe auf neue Schnittstellen"
 
-#: option.c:494
+#: option.c:510
 msgid "Export local names to global DNS"
 msgstr "Exportiere lokale Namen in das globale DNS"
 
-#: option.c:495
+#: option.c:511
 msgid "Domain to export to global DNS"
-msgstr "Domain für das Exportieren des globalen DNS"
+msgstr "Domain für globales DNS ausgeben"
 
-#: option.c:496
+#: option.c:512
 msgid "Set TTL for authoritative replies"
-msgstr "Setzte TTL für autoritative Antworten"
+msgstr "Setze Gültigkeitsdauer für autoritative Antworten"
 
-#: option.c:497
+#: option.c:513
 msgid "Set authoritative zone information"
 msgstr "Setze autoritative Zoneninformationen"
 
-#: option.c:498
+#: option.c:514
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr "Sekundärer autoritativer Nameserver für weitergeleitete Domains"
 
-#: option.c:499
+#: option.c:515
 msgid "Peers which are allowed to do zone transfer"
-msgstr "Peers welche einen Zonentransfer durchführen dürfen"
+msgstr "Peers, die einen Zonentransfer durchführen dürfen"
 
-#: option.c:500
+#: option.c:516
 msgid "Specify ipsets to which matching domains should be added"
-msgstr "Spezifiziere IPSets zu welcher passende Domains hinzugefügt werden sollen"
+msgstr "Spezifiziere IPSets, zu denen passende Domains hinzugefügt werden sollen"
 
-#: option.c:501
+#: option.c:517
+msgid "Enable filtering of DNS queries with connection-track marks."
+msgstr ""
+
+#: option.c:518
+msgid "Set allowed DNS patterns for a connection-track mark."
+msgstr ""
+
+#: option.c:519
 msgid "Specify a domain and address range for synthesised names"
 msgstr "Spezifiziere eine Domain und Adressbereich für synthetisierte Namen"
 
-#: option.c:502
+#: option.c:520
 msgid "Activate DNSSEC validation"
 msgstr "Aktiviere DNSSEC-Validierung"
 
-#: option.c:503
+#: option.c:521
 msgid "Specify trust anchor key digest."
 msgstr "Spezifiziere Vertrauensursprung (Trust Anchor) der Schlüssel-Prüfdaten (Key Digest)."
 
-#: option.c:504
+# while there is no German manual, mark "not for productive use"
+#: option.c:522
 msgid "Disable upstream checking for DNSSEC debugging."
-msgstr "Deaktiviere die Überprüfung vorgelagerter Server für DNSSEC-Debugging."
+msgstr "Deaktiviere die vorgelagerte Prüfung für die DNS-Fehlersuche. (Nicht für produktiven Einsatz!)"
 
-#: option.c:505
+#: option.c:523
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr "Stellt sicher, dass Antworten ohne DNSSEC sich in einer unsignierten Zone befinden."
 
-#: option.c:506
+#: option.c:524
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr "DNSSEC Signatur-Zeitstempel nicht prüfen, bis erstmalig der Cache neugeladen wird"
 
-#: option.c:507
+#: option.c:525
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr "Zeitstempel-Datei für die Verifizierung der Systemuhrzeit für DNSSEC"
 
-#: option.c:508
+#: option.c:526
 msgid "Set MTU, priority, resend-interval and router-lifetime"
-msgstr "Setze MTU, Priorität, Sendewiederholungsintervall und Router-Lebensdauer"
+msgstr "Setze MTU, Priorität, Sendewiederholintervall und Router-Lebensdauer"
 
-#: option.c:509
+#: option.c:527
 msgid "Do not log routine DHCP."
-msgstr "Protokolliere kein DHCP."
+msgstr "Protokolliere kein Routine-DHCP."
 
-#: option.c:510
+#: option.c:528
 msgid "Do not log routine DHCPv6."
-msgstr "Protokolliere kein DHCPv6."
+msgstr "Protokolliere kein Routine-DHCPv6."
 
-#: option.c:511
+#: option.c:529
 msgid "Do not log RA."
 msgstr "RA nicht protokollieren."
 
-#: option.c:512
+#: option.c:530
+msgid "Log debugging information."
+msgstr "Debug-(Fehlersuch-)Information protokollieren."
+
+#: option.c:531
 msgid "Accept queries only from directly-connected networks."
 msgstr "Akzeptiere nur Anfragen von direkt verbundenen Netzwerken."
 
-#: option.c:513
+#: option.c:532
 msgid "Detect and remove DNS forwarding loops."
 msgstr "Erkennen und Entfernen von DNS-Weiterleitungsschleifen."
 
-#: option.c:514
+#: option.c:533
 msgid "Ignore DNS responses containing ipaddr."
-msgstr "Ignoriere DNS-Antworten, welche ipaddr enthalten."
+msgstr "Ignoriere DNS-Antworten, die ipaddr enthalten."
 
-#: option.c:515
+#: option.c:534
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
-msgstr "Setzte TTL in DNS-Antworten mit DHCP-abgeleiteten Adressen."
+msgstr "Setze TTL in DNS-Antworten mit DHCP-abgeleiteten Adressen."
 
-#: option.c:516
+#: option.c:535
 msgid "Delay DHCP replies for at least number of seconds."
-msgstr "Verzögere DHCP-Antworten für mindestens Anzahl von Sekunden."
+msgstr "Verzögere DHCP-Antworten mindestens für gegebene Anzahl von Sekunden."
 
-#: option.c:517
+#: option.c:536
 msgid "Enables DHCPv4 Rapid Commit option."
-msgstr "Aktiviert die Option DHCPv4 Rapid Commit."
+msgstr "Aktiviert die DHCPv4-\"Rapid Commit\"-Option."
 
-#: option.c:518
+#: option.c:537
 msgid "Path to debug packet dump file"
-msgstr "Pfad zur Debug-Paketdatei, wohin gedumpt werden soll"
+msgstr "Pfad zur Paketablagedatei zur Fehlersuche"
 
-#: option.c:519
+#: option.c:538
 msgid "Mask which packets to dump"
-msgstr "Maskiere Pakete, welche gedumpt werden sollen"
+msgstr "Maskiere Pakete, welche abgelegt werden sollen"
 
-#: option.c:520
+#: option.c:539
 msgid "Call dhcp-script when lease expiry changes."
 msgstr "Rufe dhcp-script auf, wenn der Ablauf des Leases sich ändert."
 
-#: option.c:725
+#: option.c:540
+msgid "Send Cisco Umbrella identifiers including remote IP."
+msgstr ""
+
+#: option.c:541
+#, fuzzy
+msgid "Do not log routine TFTP."
+msgstr "Protokolliere kein Routine-DHCP."
+
+#: option.c:771
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -802,332 +835,373 @@ msgstr ""
 "Verwendung: dnsmasq [Optionen]\n"
 "\n"
 
-#: option.c:727
+#: option.c:773
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Auf der Befehlszeile nur kurze Optionen verwenden!\n"
 
-#: option.c:729
+#: option.c:775
 #, c-format
 msgid "Valid options are:\n"
 msgstr "Gültige Optionen sind:\n"
 
-#: option.c:776 option.c:884
+#: option.c:822 option.c:933
 msgid "bad address"
 msgstr "Fehlerhafte Adresse"
 
-#: option.c:799 option.c:803
+#: option.c:847 option.c:851
 msgid "bad port"
-msgstr "unzulässiger Port"
+msgstr "Fehlerhafter Port"
 
-#: option.c:815 option.c:844 option.c:878
+#: option.c:864 option.c:893 option.c:927
 msgid "interface binding not supported"
 msgstr "Schnittstellenbindung nicht unterstützt"
 
-#: option.c:839 option.c:873
+#: option.c:888 option.c:922
 msgid "interface can only be specified once"
 msgstr "Schnittstelle kann nur einmal angegeben werden"
 
-#: option.c:852 option.c:4042
+#: option.c:901 option.c:4362
 msgid "bad interface name"
-msgstr "unzulässiger Schnittestellenname"
+msgstr "Fehlerhafter Schnittestellenname"
+
+#: option.c:1192
+msgid "inappropriate vendor:"
+msgstr ""
+
+#: option.c:1199
+msgid "inappropriate encap:"
+msgstr ""
 
-#: option.c:1184
+#: option.c:1225
 msgid "unsupported encapsulation for IPv6 option"
 msgstr "Nicht unterstützte Verkapselung für eine IPv6-Option"
 
-#: option.c:1198
+#: option.c:1239
 msgid "bad dhcp-option"
 msgstr "Fehlerhafte DHCP-Option"
 
-#: option.c:1270
+#: option.c:1317
 msgid "bad IP address"
 msgstr "Fehlerhafte IP-Adresse"
 
-#: option.c:1273 option.c:1412 option.c:3297
+#: option.c:1320 option.c:1459 option.c:3551
 msgid "bad IPv6 address"
 msgstr "Fehlerhafte IPv6-Adresse"
 
-#: option.c:1366
+#: option.c:1413
 msgid "bad IPv4 address"
 msgstr "Fehlerhafte IPv4-Adresse"
 
-#: option.c:1439 option.c:1533
+#: option.c:1486 option.c:1581
 msgid "bad domain in dhcp-option"
 msgstr "Fehlerhafte Domäne in DHCP-Option"
 
-#: option.c:1571
+#: option.c:1625
 msgid "dhcp-option too long"
 msgstr "DHCP-Option zu lang"
 
-#: option.c:1578
+#: option.c:1632
 msgid "illegal dhcp-match"
 msgstr "Unzulässige dhcp-match-Option"
 
-#: option.c:1647
+#: option.c:1691
 msgid "illegal repeated flag"
 msgstr "unzulässig wiederholte Markierung"
 
-#: option.c:1655
+#: option.c:1699
 msgid "illegal repeated keyword"
 msgstr "unzulässig wiederholtes Schlüsselwort"
 
-#: option.c:1726 option.c:4764
+#: option.c:1770 option.c:5080
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr "Kann auf Verzeichnis %s nicht zugreifen: %s"
 
-#: option.c:1772 tftp.c:564 dump.c:68
+#: option.c:1816 tftp.c:566 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr "Kann auf %s nicht zugreifen: %s"
 
-#: option.c:1879
+#: option.c:1931
 msgid "setting log facility is not possible under Android"
-msgstr "Die Einstellung Protokolliereinrichtung kann unter Android nicht gesetzt werden"
+msgstr "Die Einstellung der \"log facility\" kann unter Android nicht gesetzt werden"
 
-#: option.c:1888
+#: option.c:1940
 msgid "bad log facility"
-msgstr "Falsche Protokolliereinrichtung"
+msgstr "Falsche \"log facility\""
 
-#: option.c:1941
+#: option.c:1993
 msgid "bad MX preference"
-msgstr "unzulässige MX-Präferenz-Angabe"
+msgstr "fehlerhafte MX-Präferenz-Angabe"
 
-#: option.c:1946
+#: option.c:1998
 msgid "bad MX name"
-msgstr "unzulässiger MX-Name"
+msgstr "fehlerhafter MX-Name"
 
-#: option.c:1960
+#: option.c:2012
 msgid "bad MX target"
-msgstr "unzulässiges MX-Ziel"
+msgstr "fehlerhaftes MX-Ziel"
 
-#: option.c:1980
+#: option.c:2032
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr "Neuübersetzung mit HAVE_SCRIPT nötig, um Lease-Änderungs-Skripte auszuführen"
 
-#: option.c:1984
+#: option.c:2036
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
-msgstr "Um Benutzerdefinierte Lua-Skripte zu ermöglichen, muss mit HAVE_LUASCRIPT neu kompiliert werden"
+msgstr "Neuübersetzung mit HAVE_LUASCRIPT nötig, um benutzerdefinierte Lua-Skripte auszuführen"
+
+#: option.c:2291 option.c:2327
+#, fuzzy
+msgid "bad prefix length"
+msgstr "fehlerhaftes Präfix"
 
-#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
+#: option.c:2303 option.c:2348 option.c:2398
 msgid "bad prefix"
-msgstr "unzulässiger Präfix"
+msgstr "fehlerhaftes Präfix"
+
+#: option.c:2418
+#, fuzzy
+msgid "prefix length too small"
+msgstr "Die Präfixlänge muss mindestens 64 sein"
+
+#: option.c:2697
+#, fuzzy
+msgid "Bad address in --address"
+msgstr "Adresse in Gebrauch"
 
-#: option.c:2658
+#: option.c:2751
+#, fuzzy
+msgid "bad IPv4 prefix"
+msgstr "fehlerhaftes IPv6-Präfix"
+
+#: option.c:2756 option.c:3569
+msgid "bad IPv6 prefix"
+msgstr "fehlerhaftes IPv6-Präfix"
+
+#: option.c:2777
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
-msgstr "Um IPSet-Direktiven zu aktivieren, muss mit HAVE_IPSET neu übersetzt werden"
+msgstr "Neuübersetzung mit HAVE_IPSET nötig, um IPSet-Direktiven zu aktivieren"
 
-#: option.c:2871
+#: option.c:2843 option.c:2861
+#, fuzzy
+msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+msgstr "Neuübersetzung mit HAVE_IPSET nötig, um IPSet-Direktiven zu aktivieren"
+
+#: option.c:3119
 msgid "bad port range"
-msgstr "unzulässiger Portbereich"
+msgstr "falscher Portbereich"
 
-#: option.c:2897
+#: option.c:3145
 msgid "bad bridge-interface"
-msgstr "unzulässige Brücken-Schnittstelle"
+msgstr "fehlerhafte Brücken-Schnittstelle"
 
-#: option.c:2941
+#: option.c:3189
 msgid "bad shared-network"
-msgstr "unzulässiger geteiltes Netz"
+msgstr "fehlerhaftes geteiltes Netz (shared-network)"
 
-#: option.c:2996
+#: option.c:3243
 msgid "only one tag allowed"
 msgstr "nur eine Marke zulässig"
 
-#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
+#: option.c:3264 option.c:3280 option.c:3406 option.c:3414 option.c:3457
 msgid "bad dhcp-range"
-msgstr "unzulässiger DHCP-Bereich"
+msgstr "fehlerhafter DHCP-Bereich"
 
-#: option.c:3050
+#: option.c:3298
 msgid "inconsistent DHCP range"
 msgstr "inkonsistenter DHCP-Bereich"
 
-#: option.c:3115
+#: option.c:3364
 msgid "prefix length must be exactly 64 for RA subnets"
-msgstr "Die Präfixlenge muss genau 64 für RA Subnetze sein"
+msgstr "Die Präfixlänge für RA-Subnetze muss genau 64 sein"
 
-#: option.c:3117
+#: option.c:3366
 msgid "prefix length must be exactly 64 for subnet constructors"
-msgstr "Die Präfixlenge muss genau 64 für Subnet Konstruktoren sein"
+msgstr "Die Präfixlänge für Subnet-Konstruktor muss genau 64 sein"
 
-#: option.c:3120
+#: option.c:3369
 msgid "prefix length must be at least 64"
 msgstr "Die Präfixlänge muss mindestens 64 sein"
 
-#: option.c:3123
+#: option.c:3372
 msgid "inconsistent DHCPv6 range"
 msgstr "Inkonsistenter DHCPv6-Bereich"
 
-#: option.c:3142
+#: option.c:3391
 msgid "prefix must be zero with \"constructor:\" argument"
-msgstr "Prefix muss mit dem \"constructor:\" Argument Null sein"
+msgstr "Präfix muss in Verbindung mit \"constructor:\" Argument Null sein"
 
-#: option.c:3262 option.c:3340
+#: option.c:3516 option.c:3594
 msgid "bad hex constant"
-msgstr "Falscher Hexwert"
-
-#: option.c:3315
-msgid "bad IPv6 prefix"
-msgstr "unzulässiger IPv6-Präfix"
+msgstr "Fehlerhafte Hex-Konstante"
 
-#: option.c:3362
+#: option.c:3617
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "doppelte dhcp-host IP-Adresse %s"
 
-#: option.c:3422
+#: option.c:3678
 msgid "bad DHCP host name"
-msgstr "unzulässiger DHCP-Hostname"
+msgstr "fehlerhafter DHCP-Hostname"
 
-#: option.c:3508
+#: option.c:3764
 msgid "bad tag-if"
-msgstr "unzulässige bedingte Marke (tag-if)"
+msgstr "fehlerhafte bedingte Marke (tag-if)"
 
-#: option.c:3851 option.c:4324
+#: option.c:4107 option.c:4623
 msgid "invalid port number"
 msgstr "unzulässige Portnummer"
 
-#: option.c:3907
+#: option.c:4163
 msgid "bad dhcp-proxy address"
 msgstr "Fehlerhafte DHCP-Proxy-Adresse"
 
-#: option.c:3935
+#: option.c:4204
 msgid "Bad dhcp-relay"
-msgstr "Uunzulässiger dhcp-relay"
+msgstr "Unzulässiges \"dhcp-relay\""
 
-#: option.c:3979
+#: option.c:4248
 msgid "bad RA-params"
-msgstr "unzulässige RA-Parameter"
+msgstr "fehlerhafte RA-Parameter"
 
-#: option.c:3989
+#: option.c:4258
 msgid "bad DUID"
-msgstr "unzulässige DUID"
+msgstr "fehlerhafte DUID"
 
-#: option.c:4023
+#: option.c:4292
 msgid "missing address in alias"
 msgstr "Adresse fehlt in Alias"
 
-#: option.c:4029
+#: option.c:4298
 msgid "invalid alias range"
 msgstr "unzulässiger Alias-Bereich"
 
-#: option.c:4081 option.c:4097
+#: option.c:4347
+msgid "missing address in dynamic host"
+msgstr "Adresse fehlt in dynamischem Host"
+
+#: option.c:4362
+msgid "bad dynamic host"
+msgstr "fehlerhafter dynamischer Host"
+
+#: option.c:4380 option.c:4396
 msgid "bad CNAME"
-msgstr "unzulässiger CNAME"
+msgstr "fehlerhafter CNAME"
 
-#: option.c:4105
+#: option.c:4404
 msgid "duplicate CNAME"
 msgstr "doppelter CNAME"
 
-#: option.c:4132
+#: option.c:4431
 msgid "bad PTR record"
-msgstr "unzulässiger PTR-Eintrag"
+msgstr "fehlerhafter PTR-Eintrag"
 
-#: option.c:4167
+#: option.c:4466
 msgid "bad NAPTR record"
-msgstr "unzulässiger NAPTR-Eintrag"
+msgstr "fehlerhafter NAPTR-Eintrag"
 
-#: option.c:4203
+#: option.c:4502
 msgid "bad RR record"
-msgstr "unzulässiger RR-Eintrag"
+msgstr "fehlerhafter RR-Eintrag"
 
-#: option.c:4236
+#: option.c:4535
 msgid "bad CAA record"
-msgstr "unzulässiger CAA-Eintrag"
+msgstr "fehlerhafter CAA-Eintrag"
 
-#: option.c:4265
+#: option.c:4564
 msgid "bad TXT record"
-msgstr "unzulässiger TXT-Eintrag"
+msgstr "fehlerhafter TXT-Eintrag"
 
-#: option.c:4308
+#: option.c:4607
 msgid "bad SRV record"
-msgstr "unzulässiger SRV-Eintrag"
+msgstr "fehlerhafter SRV-Eintrag"
 
-#: option.c:4315
+#: option.c:4614
 msgid "bad SRV target"
-msgstr "unzulässiges SRV-Ziel"
+msgstr "fehlerhaftes SRV-Ziel"
 
-#: option.c:4334
+#: option.c:4633
 msgid "invalid priority"
 msgstr "unzulässige Priorität"
 
-#: option.c:4339
+#: option.c:4638
 msgid "invalid weight"
 msgstr "unzulässige Wichtung"
 
-#: option.c:4362
+#: option.c:4661
 msgid "Bad host-record"
-msgstr "Unzulässiger host-record"
+msgstr "fehlerhafter \"host-record\""
 
-#: option.c:4402
+#: option.c:4700
 msgid "Bad name in host-record"
-msgstr "Unzulässiger Name in host-record"
+msgstr "Fehlerhafter Name in \"host-record\""
 
-#: option.c:4444
+#: option.c:4742
 msgid "bad value for dnssec-check-unsigned"
-msgstr "Ungültiger Wert für dnssec-check-unsigned"
+msgstr "Fehlerhafter Wert für \"dnssec-check-unsigned\""
 
-#: option.c:4480
+#: option.c:4778
 msgid "bad trust anchor"
-msgstr "unzulässiger Vertrauensursprung (Trust Anchor)"
+msgstr "fehlerhafter Vertrauensursprung (Trust Anchor)"
 
-#: option.c:4496
+#: option.c:4794
 msgid "bad HEX in trust anchor"
-msgstr "unzulässiger Hexwert in Vertrauensursprung (Trust Anchor)"
+msgstr "fehlerhafter Hexwert in Vertrauensursprung (Trust Anchor)"
 
-#: option.c:4507
+#: option.c:4805
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr "Nicht unterstützte Option (prüfen Sie, ob DNSMasq mit DHCP/TFTP/DNSSEC/DBus-Unterstützung übersetzt wurde)"
 
-#: option.c:4567
+#: option.c:4865
 msgid "missing \""
 msgstr "fehlende \\\""
 
-#: option.c:4624
+#: option.c:4922
 msgid "bad option"
-msgstr "unzulässige Option"
+msgstr "fehlerhafter Option"
 
-#: option.c:4626
+#: option.c:4924
 msgid "extraneous parameter"
 msgstr "überschüssiger Parameter"
 
-#: option.c:4628
+#: option.c:4926
 msgid "missing parameter"
-msgstr "fehler Parameter"
+msgstr "fehlender Parameter"
 
-#: option.c:4630
+#: option.c:4928
 msgid "illegal option"
 msgstr "unzulässige Option"
 
-#: option.c:4637
+#: option.c:4935
 msgid "error"
 msgstr "Fehler"
 
-#: option.c:4639
+#: option.c:4937
 #, c-format
 msgid " at line %d of %s"
 msgstr " in Zeile %d von %s"
 
-#: option.c:4654 option.c:4939 option.c:4950
+#: option.c:4952 option.c:5229 option.c:5240
 #, c-format
 msgid "read %s"
 msgstr "%s gelesen"
 
-#: option.c:4717 option.c:4840 tftp.c:754
+#: option.c:5015 option.c:5162 tftp.c:775
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "kann %s nicht lesen: %s"
 
-#: option.c:5027
+#: option.c:5316
 msgid "junk found in command line"
-msgstr "Mist in der Kommandozeile gefunden"
+msgstr "Müll in der Kommandozeile gefunden"
 
-#: option.c:5067
+#: option.c:5356
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Dnsmasq Version %s  %s\n"
 
-#: option.c:5068
+#: option.c:5357
 #, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1136,553 +1210,588 @@ msgstr ""
 "Kompilierungs-Optionen %s\n"
 "\n"
 
-#: option.c:5069
+#: option.c:5358
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Für diese Software wird ABSOLUT KEINE GARANTIE gewährt.\n"
 
 # FIXME: this must be one long string! -- MA
-#: option.c:5070
+#: option.c:5359
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
-msgstr "Dnsmasq ist freie Software, und du bist willkommen es weiter zu verteilen\n"
+msgstr "Dnsmasq ist freie Software, und darf unter den Bedingungen der\n"
 
-#: option.c:5071
+#: option.c:5360
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
-msgstr "unter den Bedingungen der GNU General Public Lizenz, Version 2 oder 3.\n"
+msgstr "GNU General Public Lizenz, Version 2 oder 3, weiterverteilt werden.\n"
 
-#: option.c:5088
+#: option.c:5377
 msgid "try --help"
 msgstr "versuchen Sie --help"
 
-#: option.c:5090
+#: option.c:5379
 msgid "try -w"
 msgstr "versuchen Sie -w"
 
-#: option.c:5092
+#: option.c:5381
 #, c-format
 msgid "bad command line options: %s"
-msgstr "unzulässige Optionen auf der Befehlszeile: %s"
+msgstr "fehlerhafte Optionen auf der Befehlszeile: %s"
 
-#: option.c:5161
+#: option.c:5450
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr "CNAME-Schleife mit %s"
 
-#: option.c:5195
+#: option.c:5491
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "kann Hostnamen nicht ermitteln: %s"
 
-#: option.c:5223
+#: option.c:5519
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "mit -n/--no-poll ist nur eine resolv.conf-Datei zulässig."
 
-#: option.c:5233
+#: option.c:5529
 msgid "must have exactly one resolv.conf to read domain from."
-msgstr "Um die Domäne zu lesen, muss genau eine resolv.conf-Datei verwendet werden."
+msgstr "muss genau eine resolv.conf-Datei haben, um die Domäne zu lesen."
 
-#: option.c:5236 network.c:1594 dhcp.c:876
+#: option.c:5532 network.c:1670 dhcp.c:880
 #, c-format
 msgid "failed to read %s: %s"
 msgstr "konnte %s nicht lesen: %s"
 
-#: option.c:5253
+#: option.c:5549
 #, c-format
 msgid "no search directive found in %s"
 msgstr "keine \"search\"-Anweisung in %s gefunden"
 
-#: option.c:5274
+#: option.c:5570
 msgid "there must be a default domain when --dhcp-fqdn is set"
-msgstr "Es muss eine standard Domain gesetzt sein, wenn --dhcp-fqdn gesetzt ist"
+msgstr "Es muss eine Standard-Domain gesetzt sein, wenn --dhcp-fqdn gesetzt ist"
 
-#: option.c:5283
+#: option.c:5579
 msgid "syntax check OK"
 msgstr "Syntaxprüfung OK"
 
-#: forward.c:99
+#: forward.c:104
 #, c-format
 msgid "failed to send packet: %s"
-msgstr "Fehlgeschlagen, folgendes Paket zu senden: %s"
+msgstr "Paketversand gescheitert: %s"
 
-#: forward.c:614
+#: forward.c:601
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr "Verwerfe DNS Antwort: Subnetoption stimmt nicht überrein"
 
-#: forward.c:677
+#: forward.c:666
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "Namensserver %s hat eine rekursive Anfrage verweigert"
 
-#: forward.c:709
+#: forward.c:702
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr "möglichen DNS-Rebind-Angriff entdeckt: %s"
 
-#: forward.c:961
+#: forward.c:1074
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
-msgstr "Reduziere der DNS-Paketgröße für Nameserver %s auf %d"
+msgstr "Reduziere die DNS-Paketgröße für Nameserver %s auf %d"
 
-#: forward.c:1370 forward.c:1830
+#: forward.c:1381 forward.c:1910
 msgid "Ignoring query from non-local network"
-msgstr "Ignoriere Anfragen vom nicht lokalen Netzwerk"
+msgstr "Ignoriere Anfrage von auswärtigem Netzwerk"
 
-#: forward.c:2321
+#: forward.c:2198
+#, c-format
+msgid "failed to bind server socket to %s: %s"
+msgstr "konnte nicht an Server-Socket für %s binden: %s"
+
+#: forward.c:2494
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
-msgstr "Maximale Anzahl an nebenläufiger DNS-Anfragen erreicht (Max: %d)"
+msgstr "Höchstzahl an nebenläufiger DNS-Anfragen erreicht (max. %d)"
+
+#: forward.c:2496
+#, fuzzy, c-format
+msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+msgstr "Höchstzahl an nebenläufiger DNS-Anfragen erreicht (max. %d)"
+
+#: network.c:670
+#, c-format
+msgid "stopped listening on %s(#%d): %s port %d"
+msgstr "Empfang auf %s(#%d) beendet: %s Port %d"
 
-#: network.c:698
+#: network.c:867
 #, c-format
 msgid "failed to create listening socket for %s: %s"
-msgstr "Konnte Empfangs-Socket für %s: %s nicht erzeugen"
+msgstr "Konnte Empfangs-Socket für %s nicht erzeugen: %s"
+
+#: network.c:1148
+#, c-format
+msgid "listening on %s(#%d): %s port %d"
+msgstr "Empfang auf %s(#%d): %s Port %d"
+
+#: network.c:1175
+#, c-format
+msgid "listening on %s port %d"
+msgstr "Empfang auf %s Port %d"
 
-#: network.c:1002
+#: network.c:1208
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
-msgstr "LOUD WARNING: Das Abhören von %s kann die Anfragen auf der Schnittstelle akzeptieren anders als %s"
+msgstr "LOUD WARNING: Empfang auf %s kann die Anfragen auf anderen Schnittstellen als %s akzeptieren"
 
-#: network.c:1009
+#: network.c:1215
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr "LOUD WARNING: Es sollte --bind-dynamic anstatt --bind-interfaces benutzt werden, um DNS-Verstärkungsangriffe auf diesen Schnittstellen zu unterbinden"
 
-#: network.c:1018
+#: network.c:1224
 #, c-format
 msgid "warning: using interface %s instead"
-msgstr "Warnung: Benutzer stattdessen Schnittstelle %s"
+msgstr "Warnung: benutze stattdessen Schnittstelle %s"
 
-#: network.c:1027
+#: network.c:1233
 #, c-format
 msgid "warning: no addresses found for interface %s"
-msgstr "Warnung: Keine Adresse für die Schnittstelle %s gefunden"
+msgstr "Warnung: keine Adressen für die Schnittstelle %s gefunden"
 
-#: network.c:1085
+#: network.c:1291
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "Schnittstelle %s konnte DHCPv6-Multicast-Gruppe nicht beitreten: %s"
 
-#: network.c:1090
+#: network.c:1296
 msgid "try increasing /proc/sys/net/core/optmem_max"
-msgstr "Versuche /proc/sys/net/core/optmem_max zu erhöhen"
+msgstr "Versuchen Sie, /proc/sys/net/core/optmem_max zu erhöhen"
 
-#: network.c:1307
+#: network.c:1492
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "konnte nicht an Server-Socket für %s binden: %s"
 
-#: network.c:1499
+#: network.c:1569
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignoriere Namensserver %s - lokale Schnittstelle"
 
-#: network.c:1510
+#: network.c:1580
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignoriere Namensserver %s - kann Socket nicht erzeugen/binden: %s"
 
-#: network.c:1530
+#: network.c:1598
 msgid "(no DNSSEC)"
 msgstr "(kein DNSSEC)"
 
 # FIXME: this isn't translatable - always provide full strings, do not assemble yourself! -- MA
-#: network.c:1533
+#: network.c:1601
 msgid "unqualified"
-msgstr "unqualifiziert"
+msgstr "unqualifizierte"
 
-#: network.c:1533
+#: network.c:1601
 msgid "names"
 msgstr "Namen"
 
-#: network.c:1535
+#: network.c:1603
 msgid "default"
 msgstr "Standard"
 
-#: network.c:1537
+#: network.c:1605
 msgid "domain"
-msgstr "Domain"
-
-#: network.c:1543
-#, c-format
-msgid "using only locally-known addresses for %s %s"
-msgstr "Benutze nur lokal-bekannte Adressen für %s %s"
+msgstr "Domäne"
 
-#: network.c:1546
-#, c-format
-msgid "using standard nameservers for %s %s"
-msgstr "Benutze standard Namensserver für %s %s"
-
-#: network.c:1548
-#, c-format
-msgid "using nameserver %s#%d for %s %s %s"
+#: network.c:1607
+#, fuzzy, c-format
+msgid "using nameserver %s#%d for %s %s%s %s"
 msgstr "Benutze Namensserver %s#%d für %s %s %s"
 
-#: network.c:1552
+#: network.c:1611
 #, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "Benutze Namensserver %s#%d NICHT - Anfragenschleife festgetellt"
 
-#: network.c:1555
+#: network.c:1614
 #, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "Benutze Namensserver %s#%d(via %s)"
 
-#: network.c:1557
+#: network.c:1616
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "Benutze Namensserver %s#%d"
 
-#: network.c:1562
+#: network.c:1630
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s"
+msgstr "Benutze nur lokal-bekannte Adressen für %s %s"
+
+#: network.c:1633
+#, fuzzy, c-format
+msgid "using standard nameservers for %s"
+msgstr "Benutze standard Namensserver für %s %s"
+
+#: network.c:1637
 #, c-format
 msgid "using %d more local addresses"
-msgstr "Benutze %d mehr lokale Adressen"
+msgstr "Benutze weitere %d lokale Adressen"
 
-#: network.c:1564
+#: network.c:1639
 #, c-format
 msgid "using %d more nameservers"
-msgstr "Benutze %d mehr Namensserver"
+msgstr "Benutze weitere %d Namensserver"
 
-#: dnsmasq.c:173
+#: dnsmasq.c:184
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
-msgstr "dhcp-hostsdir, dhcp-optsdir und hostsdir sind auf dieser Plattform nicht unterstüzt"
+msgstr "dhcp-hostsdir, dhcp-optsdir und hostsdir werden auf dieser Plattform nicht unterstüzt"
 
-#: dnsmasq.c:188
+#: dnsmasq.c:199
 msgid "no root trust anchor provided for DNSSEC"
-msgstr "Keine Root-Vertrauensursprünge (Root Trust Anchor) für DNSSEC verfügbar"
+msgstr "Keine Root-Vertrauensanker (Root Trust Anchor) für DNSSEC verfügbar"
 
-#: dnsmasq.c:191
+#: dnsmasq.c:202
 msgid "cannot reduce cache size from default when DNSSEC enabled"
-msgstr "Kann die Standard Cachegröße nicht verkleinern, wenn DNSSEC aktiviert ist"
+msgstr "Kann die Standard-Zwischenspeichergröße nicht verkleinern, wenn DNSSEC aktiviert ist"
 
-#: dnsmasq.c:193
+#: dnsmasq.c:204
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DNSSEC nicht verfügbar: setzen Sie HAVE_DNSSEC in src/config.h"
 
-#: dnsmasq.c:199
+#: dnsmasq.c:210
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "TFTP-Server nicht verfügbar, setzen Sie HAVE_TFTP in src/config.h"
 
-#: dnsmasq.c:204
+#: dnsmasq.c:217
 msgid "cannot use --conntrack AND --query-port"
 msgstr "Kann nicht --conntrack UND --query-port einsetzen"
 
-#: dnsmasq.c:207
+#: dnsmasq.c:223
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
-msgstr "Conntrack-Unterstützung nicht verfügbar: Aktiviere HAVE_CONNTRACK in src/config.h"
+msgstr "Conntrack-Unterstützung nicht verfügbar: Aktivieren Sie HAVE_CONNTRACK in src/config.h"
 
-#: dnsmasq.c:212
+#: dnsmasq.c:228
 msgid "asynchronous logging is not available under Solaris"
-msgstr "asynchrone Protokollierung unter Solaris nicht verfügbar"
+msgstr "asynchrone Protokollierung ist unter Solaris nicht verfügbar"
 
-#: dnsmasq.c:217
+#: dnsmasq.c:233
 msgid "asynchronous logging is not available under Android"
-msgstr "Asynchrone Protokollierung unter Android nicht verfügbar"
+msgstr "Asynchrone Protokollierung ist unter Android nicht verfügbar"
 
-#: dnsmasq.c:222
+#: dnsmasq.c:238
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
-msgstr "Authoritatives DNS nicht verfügbar: Es muss HAVE_AUTH in src/config.h gesetzt sein"
+msgstr "Autoritatives DNS nicht verfügbar: Setzen Sie HAVE_AUTH in src/config.h"
 
-#: dnsmasq.c:227
+#: dnsmasq.c:243
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
-msgstr "Loop-Erkennung nicht verfügbar, Aktiviere HAVE_LOOP in src/config.h"
+msgstr "Loop-Erkennung nicht verfügbar, aktivieren Sie HAVE_LOOP in src/config.h"
 
-#: dnsmasq.c:232
+#: dnsmasq.c:248
 msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr "UBus nicht verfügbar: setzen Sie HAVE_UBUS in src/config.h"
 
-#: dnsmasq.c:236
+#: dnsmasq.c:259
 msgid "max_port cannot be smaller than min_port"
 msgstr "max_port darf nicht kleiner als min_port sein"
 
-#: dnsmasq.c:243
+#: dnsmasq.c:266
 msgid "--auth-server required when an auth zone is defined."
-msgstr "--Auth-Server ist notwendig, wenn eine Auth-Zone definiert ist."
+msgstr "--auth-server ist notwendig, wenn eine Auth-Zone definiert ist."
 
-#: dnsmasq.c:248
+#: dnsmasq.c:271
 msgid "zone serial must be configured in --auth-soa"
-msgstr "Zonen Seriennummer muss mit --auth-soa konfiguriert werden"
+msgstr "Seriennummer der Zone muss mit --auth-soa konfiguriert werden"
 
-#: dnsmasq.c:268
+#: dnsmasq.c:291
 msgid "dhcp-range constructor not available on this platform"
-msgstr "dhcp-range Konstruktor ist auf dieser Plattform nicht verfübar"
+msgstr "dhcp-range-Konstruktor ist auf dieser Plattform nicht verfügbar"
 
-#: dnsmasq.c:332
+#: dnsmasq.c:355
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr "Kann nicht --bind-interfaces und --bind-dynamic setzen"
 
-#: dnsmasq.c:335
+#: dnsmasq.c:358
 #, c-format
 msgid "failed to find list of interfaces: %s"
-msgstr "konnte Schnitstellenliste nicht beziehen: %s"
+msgstr "konnte Schnitstellenliste nicht auffinden: %s"
 
-#: dnsmasq.c:344
+#: dnsmasq.c:367
 #, c-format
 msgid "unknown interface %s"
 msgstr "unbekannte Schnittstelle %s"
 
-#: dnsmasq.c:406
+#: dnsmasq.c:437
 msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
-msgstr "Paketdump nicht verfügbar: setzen Sie HAVE_DUMP in src/config.h"
+msgstr "Paketmitschnitt nicht verfügbar: setzen Sie HAVE_DUMP in src/config.h"
 
-#: dnsmasq.c:416 dnsmasq.c:1171
+#: dnsmasq.c:445 dnsmasq.c:1207
 #, c-format
 msgid "DBus error: %s"
 msgstr "DBus-Fehler: %s"
 
-#: dnsmasq.c:419
+#: dnsmasq.c:448
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus nicht verfügbar: setzen Sie HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:429
+#: dnsmasq.c:456 dnsmasq.c:1228
+#, fuzzy, c-format
+msgid "UBus error: %s"
+msgstr "DBus-Fehler: %s"
+
+#: dnsmasq.c:459
 msgid "UBus not available: set HAVE_UBUS in src/config.h"
 msgstr "UBus nicht verfügbar: setzen Sie HAVE_UBUS in src/config.h"
 
-#: dnsmasq.c:459
+#: dnsmasq.c:489
 #, c-format
 msgid "unknown user or group: %s"
 msgstr "Unbekannter Benutzer oder Gruppe: %s"
 
-#: dnsmasq.c:535
+#: dnsmasq.c:565
 #, c-format
 msgid "process is missing required capability %s"
-msgstr "Prozess benötigt nicht vorhandene Fähigkeit %s"
+msgstr "Prozess benötigt verlangte Fähigkeit %s"
 
-#: dnsmasq.c:567
+#: dnsmasq.c:597
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr "kann nicht ins Wurzelverzeichnis des Dateisystems wechseln: %s"
 
 # FIXME: this and the next would need commas after the version
-#: dnsmasq.c:815
+#: dnsmasq.c:845
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr "gestartet, Version %s, DNS abgeschaltet"
 
-#: dnsmasq.c:820
+#: dnsmasq.c:850
 #, c-format
 msgid "started, version %s cachesize %d"
-msgstr "gestartet, Version %s, Cachegröße %d"
+msgstr "gestartet, Version %s, Zwischenspeichergröße %d"
 
-#: dnsmasq.c:822
+#: dnsmasq.c:852
 msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
-msgstr "Die Cachegröße größer als 10000 kann Performanceprobleme verursachen und der positive Nutzen ist zudem unwahrscheinlich."
+msgstr "Eine Cachegröße größer als 10000 kann Performanceprobleme verursachen und Nutzen ist wenig wahrscheinlich."
 
-#: dnsmasq.c:825
+#: dnsmasq.c:855
 #, c-format
 msgid "started, version %s cache disabled"
-msgstr "Gestartet, Version %s Cache deaktiviert"
+msgstr "Gestartet, Version %s, Zwischenspeicher deaktiviert"
 
-#: dnsmasq.c:828
+#: dnsmasq.c:858
 msgid "DNS service limited to local subnets"
-msgstr "DNS-Dienst auf lokale Subnetze eingeschränkt"
+msgstr "DNS-Dienst auf Unternetze eingeschränkt"
 
-#: dnsmasq.c:831
+#: dnsmasq.c:861
 #, c-format
 msgid "compile time options: %s"
-msgstr "Übersetzungsoptionen: %s"
+msgstr "Optionen bei Übersetzung: %s"
 
-#: dnsmasq.c:840
+#: dnsmasq.c:870
 msgid "DBus support enabled: connected to system bus"
 msgstr "DBus-Unterstützung eingeschaltet: mit Systembus verbunden"
 
-#: dnsmasq.c:842
+#: dnsmasq.c:872
 msgid "DBus support enabled: bus connection pending"
 msgstr "DBus-Unterstützung eingeschaltet: warte auf Systembus-Verbindung"
 
-#: dnsmasq.c:850
+#: dnsmasq.c:880
 msgid "UBus support enabled: connected to system bus"
-msgstr "UBus-Unterstützung aktiviert: Mit Systembus verbunden"
+msgstr "UBus-Unterstützung aktiviert: mit Systembus verbunden"
 
-#: dnsmasq.c:852
+#: dnsmasq.c:882
 msgid "UBus support enabled: bus connection pending"
-msgstr "UBus-Unterstützung aktiviert: BUS-Verbindung wird hergestellt"
+msgstr "UBus-Unterstützung aktiviert: Bus-Verbindung wird hergestellt"
 
-#: dnsmasq.c:872
+#: dnsmasq.c:902
 msgid "DNSSEC validation enabled but all unsigned answers are trusted"
 msgstr "DNSSEC-Validierung aktiviert, jedoch wird allen unsignierten Antworten vertraut"
 
-#: dnsmasq.c:874
+#: dnsmasq.c:904
 msgid "DNSSEC validation enabled"
 msgstr "DNSSEC-Validierung aktiviert"
 
-#: dnsmasq.c:878
+#: dnsmasq.c:908
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr "DNSSEC-Signatur-Zeitstempel werden erst nach Empfang von SIGINT überprüft"
 
-#: dnsmasq.c:881
+#: dnsmasq.c:911
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr "DNSSEC Signatur-Zeitstempel werden erst überprüft, sobald die Systemuhrzeit gültig ist"
 
-#: dnsmasq.c:884
+#: dnsmasq.c:914
 #, c-format
 msgid "configured with trust anchor for %s keytag %u"
-msgstr "konfiguriert mit Vertrauensanker für% s Schlüsselwort % u"
+msgstr "konfiguriert mit Vertrauensanker für %s Schlüsselanhänger %u"
 
-#: dnsmasq.c:890
+#: dnsmasq.c:920
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "Warnung: konnte den Besitzer von %s nicht ändern: %s"
 
-#: dnsmasq.c:894
+#: dnsmasq.c:924
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "Aktiviere --bind-interfaces wegen Einschränkungen des Betriebssystems"
 
-#: dnsmasq.c:906
+#: dnsmasq.c:936
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "Warnung: Schnittstelle %s existiert derzeit nicht"
 
-#: dnsmasq.c:911
+#: dnsmasq.c:941
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr "Warnung: Ignoriere \"resolv-file\", weil \"no-resolv\" aktiv ist"
 
-#: dnsmasq.c:914
+#: dnsmasq.c:944
 msgid "warning: no upstream servers configured"
-msgstr "Warnung: keine vorgelagerten (Upstream) Server konfiguriert"
+msgstr "Warnung: keine vorgeschalteten Server konfiguriert"
 
-#: dnsmasq.c:918
+#: dnsmasq.c:948
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr "asynchrone Protokollierung eingeschaltet, Warteschlange fasst %d Nachrichten"
 
-#: dnsmasq.c:939
+#: dnsmasq.c:969
 msgid "IPv6 router advertisement enabled"
 msgstr "IPv6-Router-Advertisement aktiviert"
 
-#: dnsmasq.c:944
+#: dnsmasq.c:974
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
-msgstr "DHCP, Sockets exklusiv an das Interface %s gebunden"
+msgstr "DHCP, Sockets exklusiv an die Schnittstelle %s gebunden"
 
 # FIXME: this and the next few must be full strings to be translatable - do not assemble in code"
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "root is "
 msgstr "Wurzel ist "
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "enabled"
 msgstr "Aktiviert"
 
-#: dnsmasq.c:960
+#: dnsmasq.c:993
 msgid "secure mode"
 msgstr "sicherer Modus"
 
-#: dnsmasq.c:961
+#: dnsmasq.c:994
 msgid "single port mode"
 msgstr "Einzelport-Modus"
 
-#: dnsmasq.c:964
+#: dnsmasq.c:997
 #, c-format
 msgid "warning: %s inaccessible"
-msgstr "Warnung: %s nicht zugreifbar"
+msgstr "Warnung: %s unerreichbar"
 
-#: dnsmasq.c:968
+#: dnsmasq.c:1001
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
-msgstr "Warnung: Das TFTP-Verzeichnis %s ist nicht zugreifbar"
+msgstr "Warnung: Das TFTP-Verzeichnis %s ist unerreichbar"
 
-#: dnsmasq.c:994
+#: dnsmasq.c:1027
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr "Begrenze gleichzeitige TFTP-Übertragungen auf maximal %d"
 
-#: dnsmasq.c:1173
+#: dnsmasq.c:1204
 msgid "connected to system DBus"
 msgstr "Mit System-DBus verbunden"
 
-#: dnsmasq.c:1345
+#: dnsmasq.c:1225
+#, fuzzy
+msgid "connected to system UBus"
+msgstr "Mit System-UBus verbunden"
+
+#: dnsmasq.c:1391
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr "kann nicht in den Hintergrund abspalten: %s"
 
-#: dnsmasq.c:1349
+#: dnsmasq.c:1395
 #, c-format
 msgid "failed to create helper: %s"
 msgstr "kann Helfer nicht erzeugen: %s"
 
-#: dnsmasq.c:1353
+#: dnsmasq.c:1399
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr "kann \"capabilities\" nicht setzen: %s"
 
-#: dnsmasq.c:1357
+#: dnsmasq.c:1403
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "Kann nicht Benutzerrechte %s annehmen: %s"
 
-#: dnsmasq.c:1361
+#: dnsmasq.c:1407
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "Kann nicht Gruppenrechte %s annehmen: %s"
 
-#: dnsmasq.c:1365
+#: dnsmasq.c:1411
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "kann die Prozessidentifikations-(PID)-Datei %s nicht öffnen: %s"
 
-#: dnsmasq.c:1369
+#: dnsmasq.c:1415
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr "Kann Logdatei %s nicht öffnen: %s"
 
-#: dnsmasq.c:1373
+#: dnsmasq.c:1419
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr "Konnte Lua-Script nicht laden: %s"
 
-#: dnsmasq.c:1377
+#: dnsmasq.c:1423
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
-msgstr "Das TFTP-Verzeichnis %s ist nicht zugreifbar: %s"
+msgstr "Das TFTP-Verzeichnis %s ist unerreichbar: %s"
 
-#: dnsmasq.c:1381
+#: dnsmasq.c:1427
 #, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "Kann keine Zeitstempel-Datei %s erzeugen: %s"
 
-#: dnsmasq.c:1465
+#: dnsmasq.c:1511
 #, c-format
 msgid "script process killed by signal %d"
-msgstr "Scriptprozess durch Signal %d getötet"
+msgstr "Skriptprozess durch Signal %d beendet"
 
-#: dnsmasq.c:1469
+#: dnsmasq.c:1515
 #, c-format
 msgid "script process exited with status %d"
 msgstr "Scriptprozess hat sich mit Status %d beendet"
 
-#: dnsmasq.c:1473
+#: dnsmasq.c:1519
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr "konnte %s nicht ausführen: %s"
 
-#: dnsmasq.c:1513
+#: dnsmasq.c:1559
 msgid "now checking DNSSEC signature timestamps"
-msgstr "Prüfe jetzt DNSSEC Signatur-Zeitstempel"
+msgstr "Prüfe jetzt Zeitstempel der DNSSEC-Signaturen"
 
-#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
+#: dnsmasq.c:1594 dnssec.c:160 dnssec.c:204
 #, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "kann die mtime nicht auf %s aktualisieren: %s"
 
-#: dnsmasq.c:1560
+#: dnsmasq.c:1606
 msgid "exiting on receipt of SIGTERM"
 msgstr "beende nach Empfang von SIGTERM"
 
-#: dnsmasq.c:1588
+#: dnsmasq.c:1634
 #, c-format
 msgid "failed to access %s: %s"
 msgstr "konnte auf %s nicht zugreifen: %s"
 
-#: dnsmasq.c:1618
+#: dnsmasq.c:1664
 #, c-format
 msgid "reading %s"
 msgstr "lese %s"
 
-#: dnsmasq.c:1629
+#: dnsmasq.c:1675
 #, c-format
 msgid "no servers found in %s, will retry"
-msgstr "keine Server in %s gefunden, werde es später neu versuchen"
+msgstr "keine Server in %s gefunden, werde nochmal versuchen"
 
 #: dhcp.c:53
 #, c-format
@@ -1722,42 +1831,42 @@ msgstr "DHCP-Paket ohne Adresse an Schnittstelle %s empfangen"
 #: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
-msgstr "APR-Cache Injektion fehlgeschlagen: %s"
+msgstr "Einspeisen in ARP-Zwischenspeicher fehlgeschlagen: %s"
 
-#: dhcp.c:471
+#: dhcp.c:473
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr "Fehler beim Senden des DHCP-Pakets an %s: %s"
 
-#: dhcp.c:526
+#: dhcp.c:530
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "DHCP-Bereich %s - %s passt nicht zur Netzmaske %s"
 
-#: dhcp.c:914
+#: dhcp.c:918
 #, c-format
 msgid "bad line at %s line %d"
 msgstr "ungültige Zeile %2$d in Datei %1$s"
 
-#: dhcp.c:957
+#: dhcp.c:961
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr "ignoriere %s Zeile %d, doppelter Name oder doppelte IP-Adresse"
 
-#: dhcp.c:1100 rfc3315.c:2139
+#: dhcp.c:1105 rfc3315.c:2182
 #, c-format
 msgid "DHCP relay %s -> %s"
-msgstr "DHCP Weiterleitung %s -> %s"
+msgstr "DHCP Relais %s -> %s"
 
 #: lease.c:64
 #, c-format
 msgid "ignoring invalid line in lease database: %s %s %s %s ..."
-msgstr "ignoriere fehlerhafte Zeile in Lease-Datenbank: %s %s %s %s ..."
+msgstr "ignoriere ungültige Zeile in Lease-Datenbank: %s %s %s %s ..."
 
 #: lease.c:101
 #, c-format
 msgid "ignoring invalid line in lease database, bad address: %s"
-msgstr "ignoriere fehlerhafte Zeile in Lease-Datenbank, ungültige Adresse: %s"
+msgstr "ignoriere ungültige Zeile in Lease-Datenbank, fehlerhafte Adresse: %s"
 
 #: lease.c:108
 msgid "too many stored leases"
@@ -1766,11 +1875,11 @@ msgstr "zu viele Leases gespeichert"
 #: lease.c:176
 #, c-format
 msgid "cannot open or create lease file %s: %s"
-msgstr "kann Lease-Datei %s nicht öffnen: %s"
+msgstr "kann Lease-Datei %s nicht öffnen oder anlegen: %s"
 
 #: lease.c:185
 msgid "failed to parse lease database cleanly"
-msgstr "Fehler beim korrekten Parsen der Lease-Datenbank"
+msgstr "sauberes Aufgliedern der Lease-Datenbank fehlgeschlagen"
 
 #: lease.c:188
 #, c-format
@@ -1780,17 +1889,16 @@ msgstr "konnte Lease-Datei %s nicht lesen: %s"
 #: lease.c:204
 #, c-format
 msgid "cannot run lease-init script %s: %s"
-msgstr "kann Lease-Start-Skript %s nicht ausführen: %s"
+msgstr "kann lease-init-Skript %s nicht ausführen: %s"
 
 #: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
-msgstr "Lease-Start-Skript beendete sich mit Code %s"
+msgstr "lease-init-Skript beendete sich mit Code %s"
 
-# FIXME: This should be %u s also in English according to NIST and SI rules. -- MA
 #: lease.c:381
 #, c-format
-msgid "failed to write %s: %s (retry in %us)"
+msgid "failed to write %s: %s (retry in %u s)"
 msgstr "Konnte %s nicht schreiben: %s (Neuversuch in %u s)"
 
 #: lease.c:955
@@ -1798,208 +1906,208 @@ msgstr "Konnte %s nicht schreiben: %s (Neuversuch in %u s)"
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr "Ignoriere Domäne %s für DHCP-Hostnamen %s"
 
-# FIXME: this and the next few are not translatable. Please provide full
-# strings, do not programmatically assemble them.
-#: rfc2131.c:372
-#, c-format
-msgid "no address range available for DHCP request %s %s"
-msgstr "Kein verfügbarer DHCP-Bereich für Anfrage %s %s"
-
-#: rfc2131.c:373
+#: rfc2131.c:378
 msgid "with subnet selector"
 msgstr "mit Subnetz-Wähler"
 
-#: rfc2131.c:373
+#: rfc2131.c:383
 msgid "via"
 msgstr "via"
 
-#: rfc2131.c:385
+# FIXME: this and the next few are not translatable. Please provide full
+# strings, do not programmatically assemble them.
+#: rfc2131.c:389
+#, c-format
+msgid "no address range available for DHCP request %s %s"
+msgstr "Kein verfügbarer Adress-Bereich für DHCP-Anfrage %s %s"
+
+#: rfc2131.c:403
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
-msgstr "%u verfügbare(s) DHCP-Subnetz: %s/%s"
+msgstr "%u verfügbares DHCP-Subnetz: %s/%s"
 
-#: rfc2131.c:388 rfc3315.c:319
+#: rfc2131.c:409 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
-msgstr "%u verfügbare(r) DHCP-Bereich: %s - %s"
+msgstr "%u verfügbarer DHCP-Bereich: %s - %s"
 
-#: rfc2131.c:499
+#: rfc2131.c:521
 #, c-format
 msgid "%u vendor class: %s"
 msgstr "%u \"Vendor class\": %s"
 
-#: rfc2131.c:501
+#: rfc2131.c:523
 #, c-format
 msgid "%u user class: %s"
 msgstr "%u Benutzerklasse: %s"
 
 # FIXME: do not programmatically assemble strings - untranslatable
-#: rfc2131.c:535
+#: rfc2131.c:557
 msgid "disabled"
 msgstr "deaktiviert"
 
-#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
-#: rfc3315.c:1097
+#: rfc2131.c:598 rfc2131.c:1087 rfc2131.c:1532 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1121
 msgid "ignored"
 msgstr "ignoriert"
 
-#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
+#: rfc2131.c:613 rfc2131.c:1333 rfc3315.c:867
 msgid "address in use"
-msgstr "Adresse in Nutzung"
+msgstr "Adresse in Gebrauch"
 
-#: rfc2131.c:605 rfc2131.c:1119
+#: rfc2131.c:627 rfc2131.c:1141
 msgid "no address available"
-msgstr "Keine Adresse verfügbar"
+msgstr "keine Adresse verfügbar"
 
-#: rfc2131.c:612 rfc2131.c:1273
+#: rfc2131.c:634 rfc2131.c:1295
 msgid "wrong network"
 msgstr "Falsches Netzwerk"
 
-#: rfc2131.c:627
+#: rfc2131.c:649
 msgid "no address configured"
-msgstr "Keine Adresse konfiguriert"
+msgstr "keine Adresse konfiguriert"
 
-#: rfc2131.c:633 rfc2131.c:1323
+#: rfc2131.c:655 rfc2131.c:1346
 msgid "no leases left"
-msgstr "Keine Leases übrig"
+msgstr "keine Leases übrig"
 
-#: rfc2131.c:734 rfc3315.c:499
+#: rfc2131.c:756 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr "%u Klient stellt Name bereit: %s"
 
-#: rfc2131.c:864
+#: rfc2131.c:885
 msgid "PXE BIS not supported"
 msgstr "PXE BIS nicht unterstützt"
 
-#: rfc2131.c:1032 rfc3315.c:1197
+#: rfc2131.c:1054 rfc3315.c:1222
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "schalte statische DHCP-Adresse %s für %s ab"
 
 # FIXME: do not assemble
-#: rfc2131.c:1053
+#: rfc2131.c:1075
 msgid "unknown lease"
-msgstr "Unbekannter Lease"
+msgstr "Unbekannte Lease"
 
-#: rfc2131.c:1088
+#: rfc2131.c:1110
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr "benutze konfigurierte Adresse %s nicht, weil sie an %s verleast ist"
 
-#: rfc2131.c:1098
+#: rfc2131.c:1120
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr "benutze konfigurierte Adresse %s nicht, weil sie von Server/Relais verwendet wird"
 
-#: rfc2131.c:1101
+#: rfc2131.c:1123
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr "benutze konfigurierte Adresse %s nicht, weil sie zuvor abgelehnt wurde"
 
 # FIXME: do not assemble
-#: rfc2131.c:1117 rfc2131.c:1316
+#: rfc2131.c:1139 rfc2131.c:1339
 msgid "no unique-id"
-msgstr "Keine eindeutige ID"
+msgstr "keine eindeutige ID"
 
-#: rfc2131.c:1209
+#: rfc2131.c:1231
 msgid "wrong server-ID"
-msgstr "Falsche Server-ID"
+msgstr "falsche Server-ID"
 
-#: rfc2131.c:1228
+#: rfc2131.c:1250
 msgid "wrong address"
-msgstr "Falsche Adresse"
+msgstr "falsche Adresse"
 
-#: rfc2131.c:1246 rfc3315.c:961
+#: rfc2131.c:1268 rfc3315.c:975
 msgid "lease not found"
 msgstr "Lease nicht gefunden"
 
-#: rfc2131.c:1281
+#: rfc2131.c:1303
 msgid "address not available"
 msgstr "Adresse nicht verfügbar"
 
-#: rfc2131.c:1292
+#: rfc2131.c:1314
 msgid "static lease available"
 msgstr "Statischer Lease verfügbar"
 
-#: rfc2131.c:1296
+#: rfc2131.c:1318
 msgid "address reserved"
 msgstr "Adresse reserviert"
 
-#: rfc2131.c:1304
+#: rfc2131.c:1327
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr "Gebe Lease von %2$s an %1$s auf"
 
-#: rfc2131.c:1845
+#: rfc2131.c:1866
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr "%u Name der Bootdatei: %s"
 
-#: rfc2131.c:1854
+#: rfc2131.c:1875
 #, c-format
 msgid "%u server name: %s"
 msgstr "%u Servername: %s"
 
-#: rfc2131.c:1862
+#: rfc2131.c:1885
 #, c-format
 msgid "%u next server: %s"
 msgstr "%u nächster Server: %s"
 
-#: rfc2131.c:1865
+#: rfc2131.c:1889
 #, c-format
 msgid "%u broadcast response"
-msgstr "%u Antwort per Rundsendung"
+msgstr "%u Antwort per Broadcast"
 
-#: rfc2131.c:1928
+#: rfc2131.c:1952
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "kann DHCP/BOOTP-Opition %d nicht setzen: kein Platz mehr im Paket"
 
-#: rfc2131.c:2219
+#: rfc2131.c:2262
 msgid "PXE menu too large"
 msgstr "PXE-Menüeintrag zu groß"
 
-#: rfc2131.c:2358 rfc3315.c:1470
+#: rfc2131.c:2425 rfc3315.c:1511
 #, c-format
 msgid "%u requested options: %s"
 msgstr "%u angeforderte Optionen: %s"
 
-#: rfc2131.c:2675
+#: rfc2131.c:2742
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr "Kann RFC3925-Option nicht senden: zu viele Optionen für Unternehmen Nr. %d"
 
-#: rfc2131.c:2738
+#: rfc2131.c:2805
 #, c-format
 msgid "%u reply delay: %d"
 msgstr "%u Antwortverzögerung: %d"
 
-#: netlink.c:76
+#: netlink.c:93
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "kann Netlink-Socket nicht erzeugen: %s"
 
-#: netlink.c:352
+#: netlink.c:377
 #, c-format
 msgid "netlink returns error: %s"
 msgstr "Netlink liefert Fehler %s"
 
-#: dbus.c:438
+#: dbus.c:434
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr "Aktiviere --%s Option von D-Bus"
 
-#: dbus.c:443
+#: dbus.c:439
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr "Deaktiviere --%s Option von D-Bus"
 
-#: dbus.c:717
+#: dbus.c:713
 msgid "setting upstream servers from DBus"
-msgstr "vorgelagerte Server von DBus gesetzt"
+msgstr "vorgeschaltete Server von DBus festgelegt"
 
-#: dbus.c:764
+#: dbus.c:760
 msgid "could not register a DBus message handler"
 msgstr "konnte Steuerungsprogramm für DBus-Nachrichten nicht anmelden"
 
@@ -2016,41 +2124,46 @@ msgstr "DHCP-Anfrage für nicht unterstützen Hardwaretyp (%d) auf %s empfangen"
 #: bpf.c:374
 #, c-format
 msgid "cannot create PF_ROUTE socket: %s"
-msgstr "Kann PF_ROUTE socket nicht erzeugen: %s"
+msgstr "Kann PF_ROUTE-Socket nicht erzeugen: %s"
 
 #: bpf.c:395
 msgid "Unknown protocol version from route socket"
-msgstr "Unbekannte Protokollversion vom Route Socket"
+msgstr "Unbekannte Protokollversion vom Route-Socket"
 
 #: helper.c:150
 msgid "lease() function missing in Lua script"
-msgstr "Die Funktion lease() fehlt im Lua-Script"
+msgstr "lease()-Funktion fehlt im Lua-Skript"
 
-#: tftp.c:347
+#: tftp.c:349
 msgid "unable to get free port for TFTP"
 msgstr "konnte keinen freien Port für TFTP bekommen"
 
-#: tftp.c:363
+#: tftp.c:365
 #, c-format
 msgid "unsupported request from %s"
 msgstr "nicht unterstützte Anfrage von %s"
 
-#: tftp.c:510
+#: tftp.c:512
 #, c-format
 msgid "file %s not found"
 msgstr "Datei %s nicht gefunden"
 
-#: tftp.c:628
+#: tftp.c:602
+#, c-format
+msgid "ignoring packet from %s (TID mismatch)"
+msgstr ""
+
+#: tftp.c:646
 #, c-format
 msgid "failed sending %s to %s"
 msgstr "konnte %s nicht an %s senden"
 
-#: tftp.c:628
+#: tftp.c:646
 #, c-format
 msgid "sent %s to %s"
 msgstr "%s an %s verschickt"
 
-#: tftp.c:678
+#: tftp.c:696
 #, c-format
 msgid "error %d %s received from %s"
 msgstr "Fehler %d %s von %s empfangen"
@@ -2065,9 +2178,9 @@ msgstr "Überlauf: %d Protokolleinträge verloren"
 msgid "log failed: %s"
 msgstr "Protokollierung fehlgeschlagen: %s"
 
-#: log.c:471
+#: log.c:477
 msgid "FAILED to start up"
-msgstr "Start fehlgeschlagen"
+msgstr "Start FEHLGESCHLAGEN"
 
 #: conntrack.c:63
 #, c-format
@@ -2092,7 +2205,7 @@ msgstr "Kann nicht an DHCPv6-Server-Socket binden: %s"
 #: rfc3315.c:173
 #, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
-msgstr "Kein Adressbereich verfügbar für die DHCPv6-Anfrage vom Relay bei %s"
+msgstr "Kein Adressbereich verfügbar für die DHCPv6-Anfrage vom Relais bei %s"
 
 #: rfc3315.c:182
 #, c-format
@@ -2102,7 +2215,7 @@ msgstr "Kein Adressbereich verfügbar für die DHCPv6-Anfrage via %s"
 #: rfc3315.c:316
 #, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
-msgstr "%u verfügbare(s) DHCPv6-Subnetz: %s/%d"
+msgstr "%u verfügbares DHCPv6-Subnetz: %s/%d"
 
 #: rfc3315.c:399
 #, c-format
@@ -2118,126 +2231,126 @@ msgstr "%u Klient MAC-Adresse: %s"
 msgid "address unavailable"
 msgstr "Adresse nicht verfügbar"
 
-#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1272
 msgid "success"
 msgstr "Erfolg"
 
-#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913 rfc3315.c:1047
 msgid "no addresses available"
-msgstr "Keine Adressen verfügbar"
+msgstr "keine Adressen verfügbar"
 
 #: rfc3315.c:890
 msgid "not on link"
 msgstr "nicht on link"
 
-#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
+#: rfc3315.c:979 rfc3315.c:1180 rfc3315.c:1261
 msgid "no binding found"
 msgstr "Keine Bindung gefunden"
 
-#: rfc3315.c:1002
+#: rfc3315.c:1016
 msgid "deprecated"
 msgstr "veraltet"
 
-#: rfc3315.c:1007
+#: rfc3315.c:1023
 msgid "address invalid"
 msgstr "Adresse ungültig"
 
-#: rfc3315.c:1057 rfc3315.c:1059
+#: rfc3315.c:1081 rfc3315.c:1083
 msgid "confirm failed"
 msgstr "Bestätigung fehlgeschlagen"
 
-#: rfc3315.c:1074
+#: rfc3315.c:1098
 msgid "all addresses still on link"
-msgstr "Alle Adressen immer noch on link"
+msgstr "Alle Adressen immer noch in Verbindung"
 
-#: rfc3315.c:1165
+#: rfc3315.c:1189
 msgid "release received"
 msgstr "Freigabe empfangen"
 
-#: rfc3315.c:2130
+#: rfc3315.c:2173
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr "Kann nicht zum DHCPv6 Server multicasten ohne korrekte Schnittstelle"
 
-#: dhcp-common.c:145
+#: dhcp-common.c:154
 #, c-format
 msgid "Ignoring duplicate dhcp-option %d"
 msgstr "Ignoriere doppelt vorhandene DHCP-Option %d"
 
-#: dhcp-common.c:222
+#: dhcp-common.c:231
 #, c-format
 msgid "%u tags: %s"
 msgstr "%u Marken: %s"
 
-#: dhcp-common.c:444
+#: dhcp-common.c:451
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr "%s hat mehr als eine Adresse in hosts-Datei, benutze %s für DHCP"
 
-#: dhcp-common.c:478
+#: dhcp-common.c:485
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "doppelte IP-Adresse %s (%s) in \"dhcp-config\"-Anweisung"
 
-#: dhcp-common.c:542
+#: dhcp-common.c:549
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "kann SO_BINDTODEVICE für DHCP-Socket nicht aktivieren: %s"
 
-#: dhcp-common.c:665
+#: dhcp-common.c:672
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr "Bekannte DHCP-Optionen:\n"
 
-#: dhcp-common.c:676
+#: dhcp-common.c:683
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr "Bekannte DHCPv6-Optionen:\n"
 
-#: dhcp-common.c:873
+#: dhcp-common.c:880
 msgid ", prefix deprecated"
-msgstr ", Prefix veraltet"
+msgstr ", Präfix veraltet"
 
-#: dhcp-common.c:876
+#: dhcp-common.c:883
 #, c-format
 msgid ", lease time "
-msgstr ", Lease Zeit "
+msgstr ", Leasezeit "
 
-#: dhcp-common.c:918
+#: dhcp-common.c:925
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
-msgstr "%s stateless auf %s%.0s%.0s%s"
+msgstr "%s zustandslos auf %s%.0s%.0s%s"
 
-#: dhcp-common.c:920
+#: dhcp-common.c:927
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "%s, nur statische Leases auf %.0s%s%s%.0s"
 
-#: dhcp-common.c:922
+#: dhcp-common.c:929
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr "%s, Proxy im Subnetz %.0s%s%.0s%.0s"
 
-#: dhcp-common.c:923
+#: dhcp-common.c:930
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "%s, IP-Bereich %s -- %s%s%.0s"
 
-#: dhcp-common.c:936
+#: dhcp-common.c:943
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr "DHCPv4-abgeleitete IPv6 Namen auf %s%s"
 
-#: dhcp-common.c:939
+#: dhcp-common.c:946
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr "Router-Advertisment auf %s%s"
 
-#: dhcp-common.c:950
+#: dhcp-common.c:957
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr "DHCP Weiterleitung von %s nach %s über %s"
 
-#: dhcp-common.c:952
+#: dhcp-common.c:959
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr "DHCP Weiterleitung von %s nach %s"
@@ -2247,31 +2360,119 @@ msgstr "DHCP Weiterleitung von %s nach %s"
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "Kann ICMPv6-Socket nicht erzeugen: %s"
 
-#: auth.c:439
+#: auth.c:464
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr "ignoriere Zonentransfer-Anfrage von %s"
 
-#: ipset.c:95
-#, c-format
-msgid "failed to find kernel version: %s"
-msgstr "konnte Kernelversion nicht finden: %s"
-
-#: ipset.c:114
+#: ipset.c:99
 #, c-format
 msgid "failed to create IPset control socket: %s"
 msgstr "konnte IPset-Kontroll-Socket nicht erzeugen: %s"
 
-#: ipset.c:226
+#: ipset.c:211
 #, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "Aktualisierung von ipset %s fehlgeschlagen: %s"
 
+#: pattern.c:29
+#, c-format
+msgid "[pattern.c:%d] Assertion failure: %s"
+msgstr ""
+
+#: pattern.c:142
+#, c-format
+msgid "Invalid DNS name: Invalid character %c."
+msgstr ""
+
+#: pattern.c:151
+msgid "Invalid DNS name: Empty label."
+msgstr ""
+
+#: pattern.c:156
+msgid "Invalid DNS name: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:170
+msgid "Invalid DNS name: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:176
+#, c-format
+msgid "Invalid DNS name: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:184
+#, c-format
+msgid "Invalid DNS name: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:189
+msgid "Invalid DNS name: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:199
+msgid "Invalid DNS name: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:204
+#, c-format
+msgid "DNS name has invalid length (%zu)."
+msgstr ""
+
+#: pattern.c:258
+#, c-format
+msgid "Invalid DNS name pattern: Invalid character %c."
+msgstr ""
+
+#: pattern.c:267
+msgid "Invalid DNS name pattern: Empty label."
+msgstr ""
+
+#: pattern.c:272
+msgid "Invalid DNS name pattern: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:285
+msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+msgstr ""
+
+#: pattern.c:295
+msgid "Invalid DNS name pattern: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:301
+#, c-format
+msgid "Invalid DNS name pattern: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:309
+#, c-format
+msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:314
+msgid "Invalid DNS name pattern: Wildcard within final two labels."
+msgstr ""
+
+#: pattern.c:319
+msgid "Invalid DNS name pattern: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:329
+msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:334
+#, c-format
+msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
+msgstr ""
+
 #: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
-msgstr "Prüfe jetzt DNSSEC Signatur-Zeitstempel."
+msgstr "Systemzeit als gültig betrachtet, prüfe jetzt DNSSEC Signatur-Zeitstempel."
 
-#: dnssec.c:902
+#: dnssec.c:1014
 #, c-format
 msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
 msgstr "Unsichere DS-Antwort für %s, bitte Domainkonfiguration und Upstream DNS-Server für DNSSEC-Unterstützung überprüfen"
@@ -2279,17 +2480,17 @@ msgstr "Unsichere DS-Antwort für %s, bitte Domainkonfiguration und Upstream DNS
 #: blockdata.c:55
 #, c-format
 msgid "pool memory in use %u, max %u, allocated %u"
-msgstr "Pool Speicher in Benutzung %u, Max %u, zugewiesen %u"
+msgstr "Speicherpool in Benutzung %u, Max %u, zugewiesen %u"
 
 #: tables.c:61
 #, c-format
 msgid "failed to access pf devices: %s"
-msgstr "konnte auf pf Geräte nicht zugreifen: %s"
+msgstr "konnte auf pf-Geräte nicht zugreifen: %s"
 
 #: tables.c:74
 #, c-format
 msgid "warning: no opened pf devices %s"
-msgstr "Warnung: Keine geöffneten pf Geräte %s"
+msgstr "Warnung: Keine geöffneten pf-Geräte %s"
 
 #: tables.c:82
 #, c-format
@@ -2299,11 +2500,11 @@ msgstr "Fehler: Kann Tabellenname %s nicht benutzen"
 #: tables.c:90
 #, c-format
 msgid "error: cannot strlcpy table name %s"
-msgstr "Fehler: Kann den Tabellennamen %s nicht strlcpy"
+msgstr "Fehler: Kann den Tabellennamen %s nicht mit strlcpy kopieren"
 
 #: tables.c:101
 #, c-format
-msgid "IPset: error:%s"
+msgid "IPset: error: %s"
 msgstr "IPset: Fehler: %s"
 
 #: tables.c:108
@@ -2328,22 +2529,22 @@ msgstr "Kann auf Pfad %s nicht zugreifen: %s"
 #: inotify.c:95
 #, c-format
 msgid "failed to create inotify: %s"
-msgstr "Kann kein inotify erzeugen: %s"
+msgstr "Kann kein \"inotify\" erzeugen: %s"
 
 #: inotify.c:111
 #, c-format
 msgid "too many symlinks following %s"
-msgstr "Zu viele nachfolgende symbolische Links folgend %s"
+msgstr "zu viele Symlinks beim Verfolgen von %s"
 
 #: inotify.c:127
 #, c-format
 msgid "directory %s for resolv-file is missing, cannot poll"
-msgstr "Verzeichnis %s für resolv-file fehlt, kann nicht pollen"
+msgstr "Verzeichnis %s für resolv-file fehlt, kann nicht abfragen"
 
 #: inotify.c:131 inotify.c:168
 #, c-format
 msgid "failed to create inotify for %s: %s"
-msgstr "Konnte inotify für %s: %s nicht erzeugen"
+msgstr "Konnte \"inotify\" für %s nicht erzeugen: %s"
 
 #: inotify.c:153
 #, c-format
@@ -2363,109 +2564,53 @@ msgstr "kann %s nicht erstellen: %s"
 #: dump.c:70
 #, c-format
 msgid "bad header in %s"
-msgstr "Unzulässiger Header in %s"
+msgstr "Fehlerhafter Kopf in %s"
 
-#: dump.c:201
+#: dump.c:205
 msgid "failed to write packet dump"
-msgstr "schreiben des Paketmitschnitt fehlgeschlagen"
+msgstr "schreiben des Paketmitschnitts fehlgeschlagen"
 
-#: dump.c:203
+#: dump.c:207
 #, c-format
 msgid "dumping UDP packet %u mask 0x%04x"
-msgstr "Dumpe UDP Paket %u Maske 0x%04x"
+msgstr "Lade UDP Paket %u Maske 0x%04x ab"
 
-#: ubus.c:52
+#: ubus.c:79
 #, c-format
 msgid "UBus subscription callback: %s subscriber(s)"
 msgstr "UBus-Subskription Rückruf: %s Teilnehmer"
 
-#: ubus.c:73
+#: ubus.c:99
 #, c-format
 msgid "Cannot reconnect to UBus: %s"
 msgstr "Kann mit UBus nicht erneut verbinden: %s"
 
-#: ubus.c:89
-msgid "Cannot initialize UBus: connection failed"
-msgstr "Kann UBus nicht initialisieren: Verbindung fehlgeschlagen"
-
-#: ubus.c:102
-#, c-format
-msgid "Cannot add object to UBus: %s"
-msgstr "Kann Objekt zu UBus nicht hinzufügen: %s"
-
-#: ubus.c:112
-msgid "Connected to system UBus"
-msgstr "Mit System-UBus verbunden"
-
-#: ubus.c:122
+#: ubus.c:135
 msgid "Cannot set UBus listeners: no connection"
 msgstr "Kann UBus-Zuhörer nicht setzen: Keine Verbindung"
 
-#: ubus.c:142
+#: ubus.c:155
 msgid "Cannot poll UBus listeners: no connection"
 msgstr "Kann UBus-Zuhörer nicht abfragen: Keine Verbindung"
 
-#: ubus.c:155
+#: ubus.c:168
 msgid "Disconnecting from UBus"
-msgstr "Mit System-UBus trennen"
+msgstr "Von System-UBus trennen"
 
-#: ubus.c:199
+#: ubus.c:179 ubus.c:326
 #, c-format
-msgid "Failed to send UBus event: %s"
-msgstr "Fehlgeschlagen, folgendes UBus-Event zu senden: %s"
-
-#~ msgid "Specify DHCPv6 prefix class"
-#~ msgstr "Spezifiziere DHCPv6 Prefix Klasse"
-
-#~ msgid "cannot run scripts under uClinux"
-#~ msgstr "unter uClinux ist die Skriptausführung nicht möglich"
-
-#~ msgid "cannot match tags in --dhcp-host"
-#~ msgstr "Kann die Tags in --dhcp-host nicht abgleichen"
-
-#~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-#~ msgstr "Versuch, via DBus eine IPv6-Serveradresse zu setzen: keine IPv6-Unterstützung"
-
-# FIXME: do not assemble
-#~ msgid "unknown prefix-class %d"
-#~ msgstr "unbekannte Präfixklasse %d"
-
-#~ msgid "bad TTL"
-#~ msgstr "unzulässige TTL"
-
-#~ msgid "error: fill_addr missused"
-#~ msgstr "Fehler: fill_addr falsch verwendet"
-
-#~ msgid "warning: pfr_add_tables: %s(%d)"
-#~ msgstr "Warnung: pfr_add_tables: %s(%d)"
-
-#~ msgid "cannot cannonicalise resolv-file %s: %s"
-#~ msgstr "Kann die resolv-file %s nicht kanonisieren: %s"
-
-#~ msgid "no interface with address %s"
-#~ msgstr "keine Schnittstelle mit Adresse %s"
-
-#~ msgid "duplicate IP address %s in dhcp-config directive."
-#~ msgstr "doppelte IP-Adresse %s in \"dhcp-config\"-Anweisung"
-
-#, fuzzy
-#~ msgid "Specify path to Lua script (no default)."
-#~ msgstr "Dateipfad für Prozesskennung (PID) festlegen (Voreinstellung: %s)."
-
-#~ msgid "only one dhcp-hostsfile allowed"
-#~ msgstr "nur eine DHCP-Hostdatei (dhcp-hostsfile) zulässig"
-
-#~ msgid "only one dhcp-optsfile allowed"
-#~ msgstr "nur eine DHCP-Optionsdatei (dhcp-optsfile) zulässig"
+msgid "UBus command failed: %d (%s)"
+msgstr ""
 
-#~ msgid "files nested too deep in %s"
-#~ msgstr "Dateien in %s zu tief verschachtelt"
+#: hash-questions.c:40
+msgid "Failed to create SHA-256 hash object"
+msgstr "Kann SHA-256-Hash-Objekt nicht erstellen"
 
-#~ msgid "TXT record string too long"
-#~ msgstr "TXT-Eintrag zu lang"
+#~ msgid "Cannot initialize UBus: connection failed"
+#~ msgstr "Kann UBus nicht initialisieren: Verbindung fehlgeschlagen"
 
-#~ msgid "failed to set IPV6 options on listening socket: %s"
-#~ msgstr "konnte IPV6-Optionen auf Empfangs-Socket nicht einstellen: %s"
+#~ msgid "Cannot add object to UBus: %s"
+#~ msgstr "Kann Objekt zu UBus nicht hinzufügen: %s"
 
-#~ msgid "failed to bind listening socket for %s: %s"
-#~ msgstr "konnte Empfangs-Socket nicht an %s binden: %s"
+#~ msgid "Failed to send UBus event: %s"
+#~ msgstr "Fehlschlag beim Sendes des UBus-Ereignisses: %s"
index c9051f4..9bd61fc 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -16,814 +16,847 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: cache.c:559
+#: cache.c:572
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:1081
+#: cache.c:1094
 #, fuzzy, c-format
 msgid "failed to load names from %s: %s"
 msgstr "no se pudo cargar nombres desde %s: %s"
 
-#: cache.c:1103 dhcp.c:927
+#: cache.c:1116 dhcp.c:931
 #, fuzzy, c-format
 msgid "bad address at %s line %d"
 msgstr "dirección errónea en %s línea %d"
 
-#: cache.c:1156 dhcp.c:943
+#: cache.c:1169 dhcp.c:947
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "nombre erróneo en %s línea %d"
 
-#: cache.c:1167 dhcp.c:1018
+#: cache.c:1180 dhcp.c:1022
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "direcciónes %s - %d leídas"
 
-#: cache.c:1283
+#: cache.c:1296
 msgid "cleared cache"
 msgstr "el caché fue liberado"
 
-#: cache.c:1345
+#: cache.c:1358
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1391
+#: cache.c:1404
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr "%s es un CNAME, no se le está dando concesión DHCP de %s"
 
-#: cache.c:1415
+#: cache.c:1428
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "no otorgando nombre %s a concesión DHCP de %s porque el nombre existe en %s con dirección %s"
 
-#: cache.c:1663
+#: cache.c:1674
 #, c-format
 msgid "time %lu"
 msgstr "tiempo %lu"
 
-#: cache.c:1664
+#: cache.c:1675
 #, fuzzy, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "tamaño de caché %d, %d/%d inserciónes de caché reutilizaron objetos no vencidos."
 
-#: cache.c:1666
+#: cache.c:1677
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr "búsquedas reenviadas %u, búsquedas respondidas localmente %u"
 
-#: cache.c:1669
+#: cache.c:1680
 #, fuzzy, c-format
 msgid "queries for authoritative zones %u"
 msgstr "Fijar TTL para respuestas autoritarias"
 
-#: cache.c:1694
+#: cache.c:1702
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr "servidor %s#%d: búsquedas enviadas %u, reintentadas o fallidas %u"
 
-#: util.c:47
+#: util.c:51
 #, fuzzy, c-format
 msgid "failed to seed the random number generator: %s"
 msgstr "no se pudo crear valor semilla para el generador de números aleatorios: %s"
 
-#: util.c:224
+#: util.c:228
 #, fuzzy
 msgid "failed to allocate memory"
 msgstr "no se pudo asignar memoria"
 
-#: util.c:281 option.c:641
+#: util.c:285 option.c:665
 msgid "could not get memory"
 msgstr "no se pudo adquirir memoria"
 
-#: util.c:302
+#: util.c:306
 #, fuzzy, c-format
 msgid "cannot create pipe: %s"
 msgstr "no se puede crear pipe: %s"
 
-#: util.c:310
+#: util.c:314
 #, fuzzy, c-format
 msgid "failed to allocate %d bytes"
 msgstr "no se pudo asignar %d bytes"
 
-#: util.c:506
+#: util.c:520
 #, c-format
 msgid "infinite"
 msgstr "infinito"
 
-#: option.c:358
+#: util.c:808
+#, fuzzy, c-format
+msgid "failed to find kernel version: %s"
+msgstr "no se pudo acoplar socket de servidor DHCP: %s"
+
+#: option.c:372
 msgid "Specify local address(es) to listen on."
 msgstr "Especificar dirección(es) locales dónde escuchar."
 
-#: option.c:359
+#: option.c:373
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Retornar ipaddr (dirección IP) para todos los hosts en los dominios especificados."
 
-#: option.c:360
+#: option.c:374
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Falsificar búsquedas reversas para rangos de dirección privados RFC1918."
 
-#: option.c:361
+#: option.c:375
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Tratar ipaddr (dirección IP) como NXDOMAIN (derrota comodín Verisign)."
 
-#: option.c:362
+#: option.c:376
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Especificar tamaño de caché en cuanto a cantidad de objetos (%s por predeterminado)."
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Especificar archivo de configuración (%s por predeterminado)."
 
-#: option.c:364
+#: option.c:378
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "NO hacer un fork hacia el fondo: correr en modo debug."
 
-#: option.c:365
+#: option.c:379
 msgid "Do NOT forward queries with no domain part."
 msgstr "NO reenviar búsquedas sin parte de dominio."
 
-#: option.c:366
+#: option.c:380
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Retornar expedientes MX auto-señaladores para hosts locales."
 
-#: option.c:367
+#: option.c:381
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Expandir nombres simples en /etc/hosts con domain-suffix (sufijo de dominio)."
 
-#: option.c:368
+#: option.c:382
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "No reenviar pedidos DNS falsos desde máquinas Windows."
 
-#: option.c:369
+#: option.c:383
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Habilitar DHCP dentro del rango brindado con duración de concesión."
 
-#: option.c:370
+#: option.c:384
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Cambiar a este grupo después del inicio (%s por predeterminado)."
 
-#: option.c:371
+#: option.c:385
 msgid "Set address or hostname for a specified machine."
 msgstr "Fijar dirección o nombre de host para una máquina especificada."
 
-#: option.c:372
+#: option.c:386
 #, fuzzy
 msgid "Read DHCP host specs from file."
 msgstr "Leer especificaciones DHCP de host desde archivo"
 
-#: option.c:373
+#: option.c:387
 #, fuzzy
 msgid "Read DHCP option specs from file."
 msgstr "Leer opciones DHCP de host desde archivo"
 
-#: option.c:374
+#: option.c:388
 #, fuzzy
 msgid "Read DHCP host specs from a directory."
 msgstr "Leer especificaciones DHCP de host desde archivo"
 
-#: option.c:375
+#: option.c:389
 #, fuzzy
 msgid "Read DHCP options from a directory."
 msgstr "Leer opciones DHCP de host desde archivo"
 
-#: option.c:376
+#: option.c:390
 msgid "Evaluate conditional tag expression."
 msgstr "Evaluar expresión condicional de etiqueta."
 
-#: option.c:377
+#: option.c:391
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "NO cargar archivo %s."
 
-#: option.c:378
+#: option.c:392
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Especificar un archivo de hosts para ser leído adicionalmente a %s."
 
-#: option.c:379
+#: option.c:393
 #, fuzzy
 msgid "Read hosts files from a directory."
 msgstr "Leer especificaciones DHCP de host desde archivo"
 
-#: option.c:380
+#: option.c:394
 msgid "Specify interface(s) to listen on."
 msgstr "Especificar interfase(s) donde escuchar."
 
-#: option.c:381
+#: option.c:395
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Especificar interfase(s) donde NO escuchar."
 
-#: option.c:382
+#: option.c:396
 #, fuzzy
 msgid "Map DHCP user class to tag."
 msgstr "Trazar clase de usuario DHCP a etiqueta."
 
-#: option.c:383
+#: option.c:397
 msgid "Map RFC3046 circuit-id to tag."
 msgstr "Trazar circuit-id (identificación de circuito) RFC3046 a etiqueta."
 
-#: option.c:384
+#: option.c:398
 msgid "Map RFC3046 remote-id to tag."
 msgstr "Trazar remote-id (identificación remota) RFC3046 a etiqueta."
 
-#: option.c:385
+#: option.c:399
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr "Trazar subscriber-id (identificación de suscritor) RFC3993 a etiqueta."
 
-#: option.c:386
+#: option.c:400
+msgid "Specify vendor class to match for PXE requests."
+msgstr ""
+
+#: option.c:401
 #, fuzzy
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "No hacer DHCP para hosts con etiqueta fijada."
 
-#: option.c:387
+#: option.c:402
 #, fuzzy
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Forzar respuestas broadcast para hosts con etiqueta fijada."
 
-#: option.c:388
+#: option.c:403
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "NO hacer un fork hacia el fondo, NO correr en modo debug."
 
-#: option.c:389
+#: option.c:404
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Asumir que somos el único servidor DHCP en la red local."
 
-#: option.c:390
+#: option.c:405
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Especificar donde almacenar concesión DHCP (%s por predeterminado)."
 
-#: option.c:391
+#: option.c:406
 msgid "Return MX records for local hosts."
 msgstr "Retornar expedientes MX para hosts locales."
 
-#: option.c:392
+#: option.c:407
 msgid "Specify an MX record."
 msgstr "Especificar un expediente MX."
 
-#: option.c:393
+#: option.c:408
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Especificar opciones BOOTP a servidor DHCP."
 
-#: option.c:394
+#: option.c:409
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "NO revisar archivo %s periódicamente, recargar solo con SIGHUP."
 
-#: option.c:395
+#: option.c:410
 msgid "Do NOT cache failed search results."
 msgstr "NO almacenar en caché resultados de búsquedas fallidas."
 
-#: option.c:396
+#: option.c:411
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Usar servidores DNS estrictamente en el órden brindado en %s."
 
-#: option.c:397
+#: option.c:412
 #, fuzzy
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Especificar opciones para ser enviadas a clientes DHCP."
 
-#: option.c:398
+#: option.c:413
 msgid "DHCP option sent even if the client does not request it."
 msgstr "Opción DHCP enviada aún si el cliente no la pide."
 
-#: option.c:399
+#: option.c:414
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Especificar puerto donde escuchar por búsquedas DNS (53 por predeterminado)."
 
-#: option.c:400
+#: option.c:415
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Tamaño máximo de paquetes UDP soportado para EDNS.0 (%s por predeterminado)."
 
-#: option.c:401
+#: option.c:416
 #, fuzzy
 msgid "Log DNS queries."
 msgstr "Bitacorear búsquedas DNS."
 
-#: option.c:402
+#: option.c:417
 #, fuzzy
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Enforzar el puerto original para búsquedas DNS subida."
 
-#: option.c:403
+#: option.c:418
 msgid "Do NOT read resolv.conf."
 msgstr "NO leer resolv.conf."
 
-#: option.c:404
+#: option.c:419
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Especificar el path hacia resolv.conf (%s por predeterminado)."
 
-#: option.c:405
+#: option.c:420
 #, fuzzy
 msgid "Specify path to file with server= options"
 msgstr "Especificar path de archivo PID (%s por predeterminado)."
 
-#: option.c:406
+#: option.c:421
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Especificar dirección(es) de servidores subida con dominios opcionales."
 
-#: option.c:407
+#: option.c:422
 #, fuzzy
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Especificar dirección(es) de servidores subida con dominios opcionales."
 
-#: option.c:408
+#: option.c:423
 msgid "Never forward queries to specified domains."
 msgstr "Nunca reenviar búsquedas a dominios especificados."
 
-#: option.c:409
+#: option.c:424
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Especificar el dominio para ser asignado en concesión DHCP."
 
-#: option.c:410
+#: option.c:425
 msgid "Specify default target in an MX record."
 msgstr "Especificar destino predeterminado en un expediente MX."
 
-#: option.c:411
+#: option.c:426
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Especificar tiempo de vida en segundos para respuestas desde /etc/hosts."
 
-#: option.c:412
+#: option.c:427
 #, fuzzy
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Especificar tiempo de vida en segundos para caché negativo."
 
-#: option.c:413
+#: option.c:428
 #, fuzzy
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Especificar tiempo de vida en segundos para respuestas desde /etc/hosts."
 
-#: option.c:414
+#: option.c:429
 #, fuzzy
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Especificar tiempo de vida en segundos para caché negativo."
 
-#: option.c:415
+#: option.c:430
 #, fuzzy
 msgid "Specify time-to-live floor for cache."
 msgstr "Especificar tiempo de vida en segundos para caché negativo."
 
-#: option.c:416
+#: option.c:431
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Cambiar a este usuario despues del inicio (%s por predeterminado)."
 
-#: option.c:417
+#: option.c:432
 #, fuzzy
 msgid "Map DHCP vendor class to tag."
 msgstr "Trazar clase de vendedor DHCP a etiqueta."
 
-#: option.c:418
+#: option.c:433
 msgid "Display dnsmasq version and copyright information."
 msgstr "Mostrar información sobre la versión y copyright de dnsmasq."
 
-#: option.c:419
+#: option.c:434
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Traducir direcciones IPv4 desde servidores subida."
 
-#: option.c:420
+#: option.c:435
 msgid "Specify a SRV record."
 msgstr "Especificar un expediente SRV."
 
-#: option.c:421
+#: option.c:436
 #, fuzzy
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr "Mostrar este mensaje. Usar --help dhcp para opciones DHCP conocidas."
 
-#: option.c:422
+#: option.c:437
 #, fuzzy, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Especificar path de archivo PID (%s por predeterminado)."
 
-#: option.c:423
+#: option.c:438
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Especificar número máximo de concesión DHCP (%s por predeterminado)."
 
-#: option.c:424
+#: option.c:439
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Responder a búsquedas DNS en base a la interfase a la cuál fueron enviadas."
 
-#: option.c:425
+#: option.c:440
 msgid "Specify TXT DNS record."
 msgstr "Especificar expediente DNS TXT."
 
-#: option.c:426
+#: option.c:441
 #, fuzzy
 msgid "Specify PTR DNS record."
 msgstr "Especificar expediente DNS PTR."
 
-#: option.c:427
+#: option.c:442
 msgid "Give DNS name to IPv4 address of interface."
 msgstr "Otorgar nombre DNS a dirección IPv4 de interfase."
 
-#: option.c:428
+#: option.c:443
 msgid "Bind only to interfaces in use."
 msgstr "Acoplar solo a interfases en uso."
 
-#: option.c:429
+#: option.c:444
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Leer información sobre hosts DHCP estáticos desde %s."
 
-#: option.c:430
+#: option.c:445
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Habilitar la interfase DBus para fijar servidores subida, etc."
 
-#: option.c:431
+#: option.c:446
 msgid "Enable the UBus interface."
 msgstr ""
 
-#: option.c:432
+#: option.c:447
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "No proveer DHCP en esta interfase, sólo proveer DNS."
 
-#: option.c:433
+#: option.c:448
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Habilitar alocación dinámica de direcciónes para BOOTP."
 
-#: option.c:434
+#: option.c:449
 #, fuzzy
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Trazar dirección MAC (con comodínes) a opción fijada."
 
-#: option.c:435
+#: option.c:450
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr "Tratar pedidos DHCP en alias como si llegaran de la interfase."
 
-#: option.c:436
+#: option.c:451
 msgid "Specify extra networks sharing a broadcast domain for DHCP"
 msgstr ""
 
-#: option.c:437
+#: option.c:452
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr "Deshabilitar verificación de direcciónes para echo ICMP en el servidor DHCP."
 
-#: option.c:438
+#: option.c:453
 #, fuzzy
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr "Archivo guión para ejecutar cuando se crea o destruye una concesión DHCP."
 
-#: option.c:439
+#: option.c:454
 #, fuzzy
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr "Archivo guión para ejecutar cuando se crea o destruye una concesión DHCP."
 
-#: option.c:440
+#: option.c:455
 #, fuzzy
 msgid "Run lease-change scripts as this user."
 msgstr "Correr archivo guión de cambio de concesión como este usuario."
 
-#: option.c:441
+#: option.c:456
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:442
+#: option.c:457
 msgid "Read configuration from all the files in this directory."
 msgstr "Leer configuración desde todos los archivos en este directorio."
 
-#: option.c:443
+#: option.c:458
 #, fuzzy
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Bitacorear a esta facilidad syslog o archivo. (DAEMON por predeterminado)"
 
-#: option.c:444
+#: option.c:459
 msgid "Do not use leasefile."
 msgstr "No usar archivo de concesión."
 
-#: option.c:445
+#: option.c:460
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Número máximo de búsquedas DNS simultáneas. (%s por predeterminado)"
 
-#: option.c:446
+#: option.c:461
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr "Liberar caché DNS al recargar %s."
 
-#: option.c:447
+#: option.c:462
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr "Ignorar nombres de host brindados por clientes DHCP."
 
-#: option.c:448
+#: option.c:463
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr "NO reutilizar campos de nombre de archivo y servidor para opciones DHCP extra."
 
-#: option.c:449
+#: option.c:464
 msgid "Enable integrated read-only TFTP server."
 msgstr "Habilitar servidor integrado TFTP solo-lectura."
 
-#: option.c:450
+#: option.c:465
 msgid "Export files by TFTP only from the specified subtree."
 msgstr "Exportar archivos vía TFTP solo del sub-árbol especificado."
 
-#: option.c:451
+#: option.c:466
 #, fuzzy
 msgid "Add client IP or hardware address to tftp-root."
 msgstr "Agregar IP de cliente a tftp-root."
 
-#: option.c:452
+#: option.c:467
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr "Permitir acceso solo a archivos pertenecientes al usuario que corre dnsmasq."
 
-#: option.c:453
+#: option.c:468
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:454
+#: option.c:469
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Número máximo de transferencias TFTP simultáneas (%s por predeterminado)."
 
-#: option.c:455
+#: option.c:470
 #, fuzzy
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Número máximo de transferencias TFTP simultáneas (%s por predeterminado)."
 
-#: option.c:456
+#: option.c:471
 msgid "Disable the TFTP blocksize extension."
 msgstr "Deshabilitar la extensión TFTP blocksize (tamaño de bloque)."
 
-#: option.c:457
+#: option.c:472
 msgid "Convert TFTP filenames to lowercase"
 msgstr "Convertir a minúsculas los nombres de archivos TFTP"
 
-#: option.c:458
+#: option.c:473
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr "Rango de puertos efímeros para ser usados en transferencias TFTP."
 
-#: option.c:459
+#: option.c:474
 msgid "Use only one port for TFTP server."
 msgstr ""
 
-#: option.c:460
+#: option.c:475
 msgid "Extra logging for DHCP."
 msgstr "Log extra para DHCP."
 
-#: option.c:461
+#: option.c:476
 msgid "Enable async. logging; optionally set queue length."
 msgstr "Habilitar registro asíncrono; opcionalmente fijar tamaño de cola."
 
-#: option.c:462
+#: option.c:477
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr "Detener revinculación DNS. Filtrar rangos de IP privados al resolver."
 
-#: option.c:463
+#: option.c:478
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr "Permitir revinculación de 127.0.0.0/8, para servidores RBL."
 
-#: option.c:464
+#: option.c:479
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr "Inhibir protección de revinculación DNS en este dominio."
 
-#: option.c:465
+#: option.c:480
 msgid "Always perform DNS queries to all servers."
 msgstr "Siempre realizar búsquedas DNS a todos los servidores."
 
-#: option.c:466
+#: option.c:481
 #, fuzzy
 msgid "Set tag if client includes matching option in request."
 msgstr "Fijar etiqueta si cliente incluye opción coincidente en pedido."
 
-#: option.c:467
+#: option.c:482
 #, fuzzy
 msgid "Set tag if client provides given name."
 msgstr "Fijar etiqueta si cliente incluye opción coincidente en pedido."
 
-#: option.c:468
+#: option.c:483
 msgid "Use alternative ports for DHCP."
 msgstr "Usar puertos alternativos para DHCP."
 
-#: option.c:469
+#: option.c:484
 #, fuzzy
 msgid "Specify NAPTR DNS record."
 msgstr "Especificar expediente DNS NAPTR."
 
-#: option.c:470
+#: option.c:485
 msgid "Specify lowest port available for DNS query transmission."
 msgstr "Especificar puerto más bajo disponible para transmisión de búsquedas DNS."
 
-#: option.c:471
+#: option.c:486
 #, fuzzy
 msgid "Specify highest port available for DNS query transmission."
 msgstr "Especificar puerto más bajo disponible para transmisión de búsquedas DNS."
 
-#: option.c:472
+#: option.c:487
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr "Usar solo nombres de dominio completamente calificados para clientes DHCP."
 
-#: option.c:473
+#: option.c:488
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr "Generar hostnames basados en direcciones MAC para clientes sin nombre."
 
-#: option.c:474
+#: option.c:489
 msgid "Use these DHCP relays as full proxies."
 msgstr "Usar estos relays DHCP como proxies completos."
 
-#: option.c:475
+#: option.c:490
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:476
+#: option.c:491
 msgid "Specify alias name for LOCAL DNS name."
 msgstr "Especificar nombre alias para nombre DNS LOCAL."
 
-#: option.c:477
+#: option.c:492
 #, fuzzy
 msgid "Prompt to send to PXE clients."
 msgstr "Aviso a ser enviado a clientes PXE."
 
-#: option.c:478
+#: option.c:493
 msgid "Boot service for PXE menu."
 msgstr "Servicio de arranque para menú PXE."
 
-#: option.c:479
+#: option.c:494
 msgid "Check configuration syntax."
 msgstr "Revisar sintaxis de configuración."
 
-#: option.c:480
+#: option.c:495
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr "Añadir direcciones MAC de los peticionarios a los filtros DNS enviados"
 
-#: option.c:481
+#: option.c:496
 #, fuzzy
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr "Añadir direcciones MAC de los peticionarios a los filtros DNS enviados"
 
-#: option.c:482
+#: option.c:497
 #, fuzzy
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Añadir direcciones MAC de los peticionarios a los filtros DNS enviados"
 
-#: option.c:483
+#: option.c:498
 #, fuzzy
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Traducir direcciones IPv4 desde servidores subida."
 
-#: option.c:484
+#: option.c:499
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr "Intento de instaurar direcciones IP secuenciales a cliente DHCP"
 
-#: option.c:485
+#: option.c:500
 #, fuzzy
 msgid "Ignore client identifier option sent by DHCP clients."
 msgstr "Ignorar nombres de host brindados por clientes DHCP."
 
-#: option.c:486
+#: option.c:501
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr "Copiar la marca de connection-track desde los filtros a las conexiones salientes"
 
-#: option.c:487
+#: option.c:502
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr "Permite a clientes DHCP realizar sus propias actualizaciones DDNS"
 
-#: option.c:488
+#: option.c:503
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr "Enviar anuncios del router a los interfases realizando DHCPv6"
 
-#: option.c:489
+#: option.c:504
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:490
+#: option.c:505
 #, fuzzy
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Especificar un expediente MX."
 
-#: option.c:491
+#: option.c:506
+msgid "Specify host record in interface subnet"
+msgstr ""
+
+#: option.c:507
 msgid "Specify certification authority authorization record"
 msgstr ""
 
-#: option.c:492
+#: option.c:508
 #, fuzzy
 msgid "Specify arbitrary DNS resource record"
 msgstr "Especificar expediente DNS TXT."
 
-#: option.c:493
+#: option.c:509
 #, fuzzy
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "interfase desconocida %s en bridge-interfase"
 
-#: option.c:494
+#: option.c:510
 msgid "Export local names to global DNS"
 msgstr "Exportar nombres DNS locales a globales"
 
-#: option.c:495
+#: option.c:511
 msgid "Domain to export to global DNS"
 msgstr "Dominio a exportar a DNS global"
 
-#: option.c:496
+#: option.c:512
 msgid "Set TTL for authoritative replies"
 msgstr "Fijar TTL para respuestas autoritarias"
 
-#: option.c:497
+#: option.c:513
 #, fuzzy
 msgid "Set authoritative zone information"
 msgstr "Fijar información de zona autoritaria"
 
-#: option.c:498
+#: option.c:514
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr "Nombres de servidor secundario autoritatorios para dominios enviados"
 
-#: option.c:499
+#: option.c:515
 msgid "Peers which are allowed to do zone transfer"
 msgstr "Colegas autorizados a la zona de transferencia (transfer)"
 
-#: option.c:500
+#: option.c:516
 msgid "Specify ipsets to which matching domains should be added"
 msgstr "Especificar los ipsets coincidentes en dominio que debrían ser añadidos"
 
-#: option.c:501
+#: option.c:517
+msgid "Enable filtering of DNS queries with connection-track marks."
+msgstr ""
+
+#: option.c:518
+msgid "Set allowed DNS patterns for a connection-track mark."
+msgstr ""
+
+#: option.c:519
 #, fuzzy
 msgid "Specify a domain and address range for synthesised names"
 msgstr "Especificar dominio y rango de direcciones para los nombres acrónimos"
 
-#: option.c:502
+#: option.c:520
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:503
+#: option.c:521
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:504
+#: option.c:522
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:505
+#: option.c:523
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:506
+#: option.c:524
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:507
+#: option.c:525
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:508
+#: option.c:526
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:509
+#: option.c:527
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:510
+#: option.c:528
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:511
+#: option.c:529
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:512
+#: option.c:530
+msgid "Log debugging information."
+msgstr ""
+
+#: option.c:531
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:513
+#: option.c:532
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:514
+#: option.c:533
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:515
+#: option.c:534
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:516
+#: option.c:535
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:517
+#: option.c:536
 msgid "Enables DHCPv4 Rapid Commit option."
 msgstr ""
 
-#: option.c:518
+#: option.c:537
 msgid "Path to debug packet dump file"
 msgstr ""
 
-#: option.c:519
+#: option.c:538
 msgid "Mask which packets to dump"
 msgstr ""
 
-#: option.c:520
+#: option.c:539
 msgid "Call dhcp-script when lease expiry changes."
 msgstr ""
 
-#: option.c:725
+#: option.c:540
+msgid "Send Cisco Umbrella identifiers including remote IP."
+msgstr ""
+
+#: option.c:541
+msgid "Do not log routine TFTP."
+msgstr ""
+
+#: option.c:771
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -832,359 +865,402 @@ msgstr ""
 "Modo de uso: dnsmasq [opciones]\n"
 "\n"
 
-#: option.c:727
+#: option.c:773
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Usar opciones cortas solo en la línea de comandos.\n"
 
-#: option.c:729
+#: option.c:775
 #, fuzzy, c-format
 msgid "Valid options are:\n"
 msgstr "Opciones válidas son :\n"
 
-#: option.c:776 option.c:884
+#: option.c:822 option.c:933
 #, fuzzy
 msgid "bad address"
 msgstr "dirección IP errónea"
 
-#: option.c:799 option.c:803
+#: option.c:847 option.c:851
 msgid "bad port"
 msgstr "puerto erróneo"
 
-#: option.c:815 option.c:844 option.c:878
+#: option.c:864 option.c:893 option.c:927
 msgid "interface binding not supported"
 msgstr "vinculación de interfase no está soportado"
 
-#: option.c:839 option.c:873
+#: option.c:888 option.c:922
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:852 option.c:4042
+#: option.c:901 option.c:4362
 #, fuzzy
 msgid "bad interface name"
 msgstr "nombre de interfase erróneo"
 
-#: option.c:1184
+#: option.c:1192
+msgid "inappropriate vendor:"
+msgstr ""
+
+#: option.c:1199
+msgid "inappropriate encap:"
+msgstr ""
+
+#: option.c:1225
 msgid "unsupported encapsulation for IPv6 option"
 msgstr "Encapsulación no soportada para opción IPv6"
 
-#: option.c:1198
+#: option.c:1239
 msgid "bad dhcp-option"
 msgstr "opción dhcp-option errónea"
 
-#: option.c:1270
+#: option.c:1317
 #, fuzzy
 msgid "bad IP address"
 msgstr "dirección IP errónea"
 
-#: option.c:1273 option.c:1412 option.c:3297
+#: option.c:1320 option.c:1459 option.c:3551
 #, fuzzy
 msgid "bad IPv6 address"
 msgstr "dirección IP errónea"
 
-#: option.c:1366
+#: option.c:1413
 #, fuzzy
 msgid "bad IPv4 address"
 msgstr "dirección IP errónea"
 
-#: option.c:1439 option.c:1533
+#: option.c:1486 option.c:1581
 msgid "bad domain in dhcp-option"
 msgstr "dominio erróneo en dhcp-option"
 
-#: option.c:1571
+#: option.c:1625
 msgid "dhcp-option too long"
 msgstr "opción dhcp-option demasiado larga"
 
-#: option.c:1578
+#: option.c:1632
 msgid "illegal dhcp-match"
 msgstr "dhcp-match ilegal"
 
-#: option.c:1647
+#: option.c:1691
 msgid "illegal repeated flag"
 msgstr "opción repetida ilegal"
 
-#: option.c:1655
+#: option.c:1699
 msgid "illegal repeated keyword"
 msgstr "palabra clave repetida ilegal"
 
-#: option.c:1726 option.c:4764
+#: option.c:1770 option.c:5080
 #, fuzzy, c-format
 msgid "cannot access directory %s: %s"
 msgstr "no se puede acceder a directorio %s: %s"
 
-#: option.c:1772 tftp.c:564 dump.c:68
+#: option.c:1816 tftp.c:566 dump.c:68
 #, fuzzy, c-format
 msgid "cannot access %s: %s"
 msgstr "no se puede acceder %s: %s"
 
-#: option.c:1879
+#: option.c:1931
 msgid "setting log facility is not possible under Android"
 msgstr "la creación de un registro no es posible en Android"
 
-#: option.c:1888
+#: option.c:1940
 msgid "bad log facility"
 msgstr "ubicación del registro errónea"
 
-#: option.c:1941
+#: option.c:1993
 msgid "bad MX preference"
 msgstr "preferencia MX errónea"
 
-#: option.c:1946
+#: option.c:1998
 msgid "bad MX name"
 msgstr "nombre MX erróneo"
 
-#: option.c:1960
+#: option.c:2012
 msgid "bad MX target"
 msgstr "destino MX erróneo"
 
-#: option.c:1980
+#: option.c:2032
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr "recompilar con HAVE_SCRIPT definido para habilitar guiónes de cambio de concesión"
 
-#: option.c:1984
+#: option.c:2036
 #, fuzzy
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr "recompilar con HAVE_SCRIPT definido para habilitar 'scripts' en Lua"
 
-#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
+#: option.c:2291 option.c:2327
+#, fuzzy
+msgid "bad prefix length"
+msgstr "prefijo erróneo"
+
+#: option.c:2303 option.c:2348 option.c:2398
 #, fuzzy
 msgid "bad prefix"
 msgstr "prefijo erróneo"
 
-#: option.c:2658
+#: option.c:2418
+#, fuzzy
+msgid "prefix length too small"
+msgstr "la longitud del prefijo debe ser al menos 64"
+
+#: option.c:2697
+#, fuzzy
+msgid "Bad address in --address"
+msgstr "dirección en uso"
+
+#: option.c:2751
+#, fuzzy
+msgid "bad IPv4 prefix"
+msgstr "prefijo erróneo"
+
+#: option.c:2756 option.c:3569
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "prefijo erróneo"
+
+#: option.c:2777
 #, fuzzy
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr "recompilar con HAVE_SCRIPT definido para habilitar directivas ipset"
 
-#: option.c:2871
+#: option.c:2843 option.c:2861
+#, fuzzy
+msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+msgstr "recompilar con HAVE_SCRIPT definido para habilitar directivas ipset"
+
+#: option.c:3119
 #, fuzzy
 msgid "bad port range"
 msgstr "rango de puertos erróneo"
 
-#: option.c:2897
+#: option.c:3145
 msgid "bad bridge-interface"
 msgstr "opción bridge-interface (interfase puente) errónea"
 
-#: option.c:2941
+#: option.c:3189
 msgid "bad shared-network"
 msgstr ""
 
-#: option.c:2996
+#: option.c:3243
 msgid "only one tag allowed"
 msgstr "solo una etiqueta permitida"
 
-#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
+#: option.c:3264 option.c:3280 option.c:3406 option.c:3414 option.c:3457
 msgid "bad dhcp-range"
 msgstr "opción dhcp-range (rango DHCP) errónea"
 
-#: option.c:3050
+#: option.c:3298
 msgid "inconsistent DHCP range"
 msgstr "rango DHCP inconsistente"
 
-#: option.c:3115
+#: option.c:3364
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr "la longitud del prefijo debe ser 64 exacto para subredes RA"
 
-#: option.c:3117
+#: option.c:3366
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr "la longitud del prefijo debe ser 64 exacto para subredes constructoras"
 
-#: option.c:3120
+#: option.c:3369
 msgid "prefix length must be at least 64"
 msgstr "la longitud del prefijo debe ser al menos 64"
 
-#: option.c:3123
+#: option.c:3372
 #, fuzzy
 msgid "inconsistent DHCPv6 range"
 msgstr "rango DHCP inconsistente"
 
-#: option.c:3142
+#: option.c:3391
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr "prefijo debe ser cero con argumento \"constructor:\""
 
-#: option.c:3262 option.c:3340
+#: option.c:3516 option.c:3594
 #, fuzzy
 msgid "bad hex constant"
 msgstr "constante hexadecimal errónea"
 
-#: option.c:3315
-#, fuzzy
-msgid "bad IPv6 prefix"
-msgstr "prefijo erróneo"
-
-#: option.c:3362
+#: option.c:3617
 #, fuzzy, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "dirección IP duplicada %s en %s."
 
-#: option.c:3422
+#: option.c:3678
 #, fuzzy
 msgid "bad DHCP host name"
 msgstr "nombre de host DHCP erróneo"
 
-#: option.c:3508
+#: option.c:3764
 #, fuzzy
 msgid "bad tag-if"
 msgstr "etiqueta tag-if errónea"
 
-#: option.c:3851 option.c:4324
+#: option.c:4107 option.c:4623
 msgid "invalid port number"
 msgstr "número de puerto inválido"
 
-#: option.c:3907
+#: option.c:4163
 #, fuzzy
 msgid "bad dhcp-proxy address"
 msgstr "dirección IP errónea"
 
-#: option.c:3935
+#: option.c:4204
 #, fuzzy
 msgid "Bad dhcp-relay"
 msgstr "opción dhcp-range (rango DHCP) errónea"
 
-#: option.c:3979
+#: option.c:4248
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3989
+#: option.c:4258
 msgid "bad DUID"
 msgstr "DUID erróneo"
 
-#: option.c:4023
+#: option.c:4292
 #, fuzzy
 msgid "missing address in alias"
 msgstr "dirección en uso"
 
-#: option.c:4029
+#: option.c:4298
 #, fuzzy
 msgid "invalid alias range"
 msgstr "rango alias inválido"
 
-#: option.c:4081 option.c:4097
+#: option.c:4347
+#, fuzzy
+msgid "missing address in dynamic host"
+msgstr "dirección en uso"
+
+#: option.c:4362
+#, fuzzy
+msgid "bad dynamic host"
+msgstr "no se puede acceder a directorio %s: %s"
+
+#: option.c:4380 option.c:4396
 msgid "bad CNAME"
 msgstr "CNAME erróneo"
 
-#: option.c:4105
+#: option.c:4404
 msgid "duplicate CNAME"
 msgstr "CNAME duplicado"
 
-#: option.c:4132
+#: option.c:4431
 #, fuzzy
 msgid "bad PTR record"
 msgstr "registro PTR erróneo"
 
-#: option.c:4167
+#: option.c:4466
 #, fuzzy
 msgid "bad NAPTR record"
 msgstr "registro NAPTR erróneo"
 
-#: option.c:4203
+#: option.c:4502
 #, fuzzy
 msgid "bad RR record"
 msgstr "registro PTR erróneo"
 
-#: option.c:4236
+#: option.c:4535
 #, fuzzy
 msgid "bad CAA record"
 msgstr "registro PTR erróneo"
 
-#: option.c:4265
+#: option.c:4564
 msgid "bad TXT record"
 msgstr "registro TXT erróneo"
 
-#: option.c:4308
+#: option.c:4607
 msgid "bad SRV record"
 msgstr "registro SRV erróneo"
 
-#: option.c:4315
+#: option.c:4614
 msgid "bad SRV target"
 msgstr "destino SRV erróneo"
 
-#: option.c:4334
+#: option.c:4633
 msgid "invalid priority"
 msgstr "prioridad inválida"
 
-#: option.c:4339
+#: option.c:4638
 msgid "invalid weight"
 msgstr "peso inválido"
 
-#: option.c:4362
+#: option.c:4661
 #, fuzzy
 msgid "Bad host-record"
 msgstr "registro PTR erróneo"
 
-#: option.c:4402
+#: option.c:4700
 #, fuzzy
 msgid "Bad name in host-record"
 msgstr "nombre erróneo en %s"
 
-#: option.c:4444
+#: option.c:4742
 msgid "bad value for dnssec-check-unsigned"
 msgstr ""
 
-#: option.c:4480
+#: option.c:4778
 #, fuzzy
 msgid "bad trust anchor"
 msgstr "rango de puertos erróneo"
 
-#: option.c:4496
+#: option.c:4794
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4507
+#: option.c:4805
 #, fuzzy
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr "opción no soportada (verificar que dnsmasq fue compilado con soporte para DHCP/TFTP/DBus)"
 
-#: option.c:4567
+#: option.c:4865
 msgid "missing \""
 msgstr "falta \""
 
-#: option.c:4624
+#: option.c:4922
 msgid "bad option"
 msgstr "opción errónea"
 
-#: option.c:4626
+#: option.c:4924
 msgid "extraneous parameter"
 msgstr "parámetro extraño"
 
-#: option.c:4628
+#: option.c:4926
 msgid "missing parameter"
 msgstr "parámetro ausente"
 
-#: option.c:4630
+#: option.c:4928
 #, fuzzy
 msgid "illegal option"
 msgstr "opción errónea"
 
-#: option.c:4637
+#: option.c:4935
 msgid "error"
 msgstr "error"
 
-#: option.c:4639
+#: option.c:4937
 #, fuzzy, c-format
 msgid " at line %d of %s"
 msgstr "%s en línea %d de %%s"
 
-#: option.c:4654 option.c:4939 option.c:4950
+#: option.c:4952 option.c:5229 option.c:5240
 #, fuzzy, c-format
 msgid "read %s"
 msgstr "lee %s"
 
-#: option.c:4717 option.c:4840 tftp.c:754
+#: option.c:5015 option.c:5162 tftp.c:775
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "no se puede leer %s: %s"
 
-#: option.c:5027
+#: option.c:5316
 msgid "junk found in command line"
 msgstr "basura encontrada en linea de comando"
 
-#: option.c:5067
+#: option.c:5356
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Versión dnsmasq %s  %s\n"
 
-#: option.c:5068
+#: option.c:5357
 #, fuzzy, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1193,563 +1269,598 @@ msgstr ""
 "Opciones de compilación %s\n"
 "\n"
 
-#: option.c:5069
+#: option.c:5358
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Este software viene SIN NINGUNA GARANTIA.\n"
 
-#: option.c:5070
+#: option.c:5359
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsmasq es software libre, y usted está autorizado a redistribuirlo\n"
 
-#: option.c:5071
+#: option.c:5360
 #, fuzzy, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "bajo los términos de la GNU General Public License, versión 2 o 3.\n"
 
-#: option.c:5088
+#: option.c:5377
 msgid "try --help"
 msgstr "pruebe --help"
 
-#: option.c:5090
+#: option.c:5379
 msgid "try -w"
 msgstr "pruebe -w"
 
-#: option.c:5092
+#: option.c:5381
 #, fuzzy, c-format
 msgid "bad command line options: %s"
 msgstr "opciones de línea de comandos erróneas: %s"
 
-#: option.c:5161
+#: option.c:5450
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:5195
+#: option.c:5491
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "no se puede obtener host-name (nombre de host): %s"
 
-#: option.c:5223
+#: option.c:5519
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "solo un archivo resolv.conf está permitido en modo no-poll."
 
-#: option.c:5233
+#: option.c:5529
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "debe haber exáctamente un resolv.conf desde donde leer dominio."
 
-#: option.c:5236 network.c:1594 dhcp.c:876
+#: option.c:5532 network.c:1670 dhcp.c:880
 #, fuzzy, c-format
 msgid "failed to read %s: %s"
 msgstr "no se pudo leer %s: %s"
 
-#: option.c:5253
+#: option.c:5549
 #, c-format
 msgid "no search directive found in %s"
 msgstr "ninguna directiva de búsqueda encontrada en %s"
 
-#: option.c:5274
+#: option.c:5570
 #, fuzzy
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr "debe haber un dominio predeterminado cuando --dhcp-fqdn está fijado"
 
-#: option.c:5283
+#: option.c:5579
 msgid "syntax check OK"
 msgstr "revisión de sintaxis OK"
 
-#: forward.c:99
+#: forward.c:104
 #, fuzzy, c-format
 msgid "failed to send packet: %s"
 msgstr "no se pudo escuchar en socket: %s"
 
-#: forward.c:614
+#: forward.c:601
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:677
+#: forward.c:666
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "servidor DNS %s rechazó realizar una búsqueda recursiva"
 
-#: forward.c:709
+#: forward.c:702
 #, fuzzy, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr "posible ataque de revinculación DNS detectado"
 
-#: forward.c:961
+#: forward.c:1074
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1370 forward.c:1830
+#: forward.c:1381 forward.c:1910
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2321
+#: forward.c:2198
+#, fuzzy, c-format
+msgid "failed to bind server socket to %s: %s"
+msgstr "no se pudo acoplar al zócalo del servidor para %s: %s"
+
+#: forward.c:2494
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Número máximo de búsquedas DNS simultáneas alcanzado. (%s por predeterminado)"
 
-#: network.c:698
+#: forward.c:2496
+#, fuzzy, c-format
+msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+msgstr "Número máximo de búsquedas DNS simultáneas alcanzado. (%s por predeterminado)"
+
+#: network.c:670
+#, c-format
+msgid "stopped listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:867
 #, fuzzy, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "no se pudo crear un zócalo de escucha: %s"
 
-#: network.c:1002
+#: network.c:1148
+#, c-format
+msgid "listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:1175
+#, fuzzy, c-format
+msgid "listening on %s port %d"
+msgstr "TFTP no pudo enviar %s a %s"
+
+#: network.c:1208
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1009
+#: network.c:1215
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1018
+#: network.c:1224
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "advertencia: interfase %s no existe actualmente"
 
-#: network.c:1027
+#: network.c:1233
 #, fuzzy, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "usando direcciones locales solo para %s %s"
 
-#: network.c:1085
+#: network.c:1291
 #, fuzzy, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "el interfase % falló al unirse al grupo multicast DHCPv6: %s"
 
-#: network.c:1090
+#: network.c:1296
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1307
+#: network.c:1492
 #, fuzzy, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "no se pudo acoplar al zócalo del servidor para %s: %s"
 
-#: network.c:1499
+#: network.c:1569
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignorando servidor DNS %s - interfase local"
 
-#: network.c:1510
+#: network.c:1580
 #, fuzzy, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignorando servidor DNS %s - no se puede crear/acoplar zócalo: %s"
 
-#: network.c:1530
+#: network.c:1598
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1533
+#: network.c:1601
 msgid "unqualified"
 msgstr "no cualificado"
 
-#: network.c:1533
+#: network.c:1601
 msgid "names"
 msgstr "nombres"
 
-#: network.c:1535
+#: network.c:1603
 msgid "default"
 msgstr "predeterminado"
 
-#: network.c:1537
+#: network.c:1605
 msgid "domain"
 msgstr "dominio"
 
-#: network.c:1543
-#, fuzzy, c-format
-msgid "using only locally-known addresses for %s %s"
-msgstr "usando direcciones locales solo para %s %s"
-
-#: network.c:1546
-#, fuzzy, c-format
-msgid "using standard nameservers for %s %s"
-msgstr "usando nombres estándar %s#%d para %s %s"
-
-#: network.c:1548
+#: network.c:1607
 #, fuzzy, c-format
-msgid "using nameserver %s#%d for %s %s %s"
+msgid "using nameserver %s#%d for %s %s%s %s"
 msgstr "usando nombre de servidor %s#%d para %s %s"
 
-#: network.c:1552
+#: network.c:1611
 #, fuzzy, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "usando nombre de servidor %s#%d para %s %s"
 
-#: network.c:1555
+#: network.c:1614
 #, fuzzy, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "usando nombre de servidor %s#%d(vía %s)"
 
-#: network.c:1557
+#: network.c:1616
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "usando nombre de servidor %s#%d"
 
-#: network.c:1562
+#: network.c:1630
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s"
+msgstr "usando direcciones locales solo para %s %s"
+
+#: network.c:1633
+#, fuzzy, c-format
+msgid "using standard nameservers for %s"
+msgstr "usando nombres estándar %s#%d para %s %s"
+
+#: network.c:1637
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "usando nombre de servidor %s#%d"
 
-#: network.c:1564
+#: network.c:1639
 #, fuzzy, c-format
 msgid "using %d more nameservers"
 msgstr "usando nombre de servidor %s#%d"
 
-#: dnsmasq.c:173
+#: dnsmasq.c:184
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:188
+#: dnsmasq.c:199
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:202
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:193
+#: dnsmasq.c:204
 #, fuzzy
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
 
-#: dnsmasq.c:199
+#: dnsmasq.c:210
 #, fuzzy
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "servidor TFTP no disponible: fijar HAVE_TFTP en src/config.h"
 
-#: dnsmasq.c:204
+#: dnsmasq.c:217
 #, fuzzy
 msgid "cannot use --conntrack AND --query-port"
 msgstr "No puede usar --conntrack AND --query-port"
 
-#: dnsmasq.c:207
+#: dnsmasq.c:223
 #, fuzzy
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "servidor TFTP no disponible: fijar HAVE_TFTP en src/config.h"
 
-#: dnsmasq.c:212
+#: dnsmasq.c:228
 #, fuzzy
 msgid "asynchronous logging is not available under Solaris"
 msgstr "registro asíncrono no está disponible bajo Solaris"
 
-#: dnsmasq.c:217
+#: dnsmasq.c:233
 #, fuzzy
 msgid "asynchronous logging is not available under Android"
 msgstr "registro asíncrono no está disponible bajo Solaris"
 
-#: dnsmasq.c:222
+#: dnsmasq.c:238
 #, fuzzy
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
 
-#: dnsmasq.c:227
+#: dnsmasq.c:243
 #, fuzzy
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "servidor TFTP no disponible: fijar HAVE_TFTP en src/config.h"
 
-#: dnsmasq.c:232
+#: dnsmasq.c:248
 #, fuzzy
 msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
 
-#: dnsmasq.c:236
+#: dnsmasq.c:259
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:243
+#: dnsmasq.c:266
 msgid "--auth-server required when an auth zone is defined."
 msgstr ""
 
-#: dnsmasq.c:248
+#: dnsmasq.c:271
 msgid "zone serial must be configured in --auth-soa"
 msgstr "zona serie debe ser configurada en --auth-soa"
 
-#: dnsmasq.c:268
+#: dnsmasq.c:291
 msgid "dhcp-range constructor not available on this platform"
 msgstr "constructor rango dhcp no disponible en esta plataforma"
 
-#: dnsmasq.c:332
+#: dnsmasq.c:355
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr "no puede usar --bind-interfases y --bind-dynamic"
 
-#: dnsmasq.c:335
+#: dnsmasq.c:358
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "no se pudo encontrar lista de interfases: %s"
 
-#: dnsmasq.c:344
+#: dnsmasq.c:367
 #, c-format
 msgid "unknown interface %s"
 msgstr "interfase desconocida %s"
 
-#: dnsmasq.c:406
+#: dnsmasq.c:437
 #, fuzzy
 msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
 msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
 
-#: dnsmasq.c:416 dnsmasq.c:1171
+#: dnsmasq.c:445 dnsmasq.c:1207
 #, c-format
 msgid "DBus error: %s"
 msgstr "error DBus: %s"
 
-#: dnsmasq.c:419
+#: dnsmasq.c:448
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
 
-#: dnsmasq.c:429
+#: dnsmasq.c:456 dnsmasq.c:1228
+#, fuzzy, c-format
+msgid "UBus error: %s"
+msgstr "error DBus: %s"
+
+#: dnsmasq.c:459
 #, fuzzy
 msgid "UBus not available: set HAVE_UBUS in src/config.h"
 msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
 
-#: dnsmasq.c:459
+#: dnsmasq.c:489
 #, c-format
 msgid "unknown user or group: %s"
 msgstr "usuario o grupo desconocido: %s"
 
-#: dnsmasq.c:535
+#: dnsmasq.c:565
 #, c-format
 msgid "process is missing required capability %s"
 msgstr ""
 
-#: dnsmasq.c:567
+#: dnsmasq.c:597
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr "no se puede cambiar directorio a raíz de sistema de archivos: %s"
 
-#: dnsmasq.c:815
+#: dnsmasq.c:845
 #, fuzzy, c-format
 msgid "started, version %s DNS disabled"
 msgstr "iniciado, versión %s DNS deshabilitado"
 
-#: dnsmasq.c:820
+#: dnsmasq.c:850
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "iniciado, versión %s tamaño de caché %d"
 
-#: dnsmasq.c:822
+#: dnsmasq.c:852
 msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
 msgstr ""
 
-#: dnsmasq.c:825
+#: dnsmasq.c:855
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "iniciado, versión %s caché deshabilitado"
 
-#: dnsmasq.c:828
+#: dnsmasq.c:858
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:831
+#: dnsmasq.c:861
 #, c-format
 msgid "compile time options: %s"
 msgstr "opciones de compilación: %s"
 
-#: dnsmasq.c:840
+#: dnsmasq.c:870
 msgid "DBus support enabled: connected to system bus"
 msgstr "soporte DBus habilitado: conectado a bus de sistema"
 
-#: dnsmasq.c:842
+#: dnsmasq.c:872
 msgid "DBus support enabled: bus connection pending"
 msgstr "soporte DBus habilitado: conexión a bus pendiente"
 
-#: dnsmasq.c:850
+#: dnsmasq.c:880
 #, fuzzy
 msgid "UBus support enabled: connected to system bus"
 msgstr "soporte DBus habilitado: conectado a bus de sistema"
 
-#: dnsmasq.c:852
+#: dnsmasq.c:882
 #, fuzzy
 msgid "UBus support enabled: bus connection pending"
 msgstr "soporte DBus habilitado: conexión a bus pendiente"
 
-#: dnsmasq.c:872
+#: dnsmasq.c:902
 msgid "DNSSEC validation enabled but all unsigned answers are trusted"
 msgstr ""
 
-#: dnsmasq.c:874
+#: dnsmasq.c:904
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:878
+#: dnsmasq.c:908
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:881
+#: dnsmasq.c:911
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:884
+#: dnsmasq.c:914
 #, c-format
 msgid "configured with trust anchor for %s keytag %u"
 msgstr ""
 
-#: dnsmasq.c:890
+#: dnsmasq.c:920
 #, fuzzy, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "advertencia: no se pudo cambiar propietario de %s: %s"
 
-#: dnsmasq.c:894
+#: dnsmasq.c:924
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "fijando opción --bind-interfases debido a limitaciones de sistema operativo"
 
-#: dnsmasq.c:906
+#: dnsmasq.c:936
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "advertencia: interfase %s no existe actualmente"
 
-#: dnsmasq.c:911
+#: dnsmasq.c:941
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr "advertencia: ignorando opción resolv-file porque no-resolv está fijado"
 
-#: dnsmasq.c:914
+#: dnsmasq.c:944
 #, fuzzy
 msgid "warning: no upstream servers configured"
 msgstr "advertencia: ningún servidor de subida configurado"
 
-#: dnsmasq.c:918
+#: dnsmasq.c:948
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr "registro asíncrono habilitado, el límite de la cola es %d mensajes"
 
-#: dnsmasq.c:939
+#: dnsmasq.c:969
 msgid "IPv6 router advertisement enabled"
 msgstr "Anuncio de router IPv6 habilitado"
 
-#: dnsmasq.c:944
+#: dnsmasq.c:974
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "root is "
 msgstr "root está "
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 #, fuzzy
 msgid "enabled"
 msgstr "habilitado"
 
-#: dnsmasq.c:960
+#: dnsmasq.c:993
 msgid "secure mode"
 msgstr "modo seguro"
 
-#: dnsmasq.c:961
+#: dnsmasq.c:994
 #, fuzzy
 msgid "single port mode"
 msgstr "número de puerto inválido"
 
-#: dnsmasq.c:964
+#: dnsmasq.c:997
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:968
+#: dnsmasq.c:1001
 #, fuzzy, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr "directorio TFTP % inaccesible: %s"
 
-#: dnsmasq.c:994
+#: dnsmasq.c:1027
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr "limitando número máximo de transferencias TFTP simultáneas a %d"
 
-#: dnsmasq.c:1173
+#: dnsmasq.c:1204
 msgid "connected to system DBus"
 msgstr "conectado a DBus de sistema"
 
-#: dnsmasq.c:1345
+#: dnsmasq.c:1225
+#, fuzzy
+msgid "connected to system UBus"
+msgstr "conectado a DBus de sistema"
+
+#: dnsmasq.c:1391
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr "no se puede hacer fork en background: %s"
 
-#: dnsmasq.c:1349
+#: dnsmasq.c:1395
 #, fuzzy, c-format
 msgid "failed to create helper: %s"
 msgstr "no se pudo crear ayudante: %s"
 
-#: dnsmasq.c:1353
+#: dnsmasq.c:1399
 #, fuzzy, c-format
 msgid "setting capabilities failed: %s"
 msgstr "configuración de capacidades ha fallado: %s"
 
-#: dnsmasq.c:1357
+#: dnsmasq.c:1403
 #, fuzzy, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "no se pudo cambiar user-id a %s: %s"
 
-#: dnsmasq.c:1361
+#: dnsmasq.c:1407
 #, fuzzy, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "no se pudo cambiar group-id a %s: %s"
 
-#: dnsmasq.c:1365
+#: dnsmasq.c:1411
 #, fuzzy, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "no se pudo abrir archivo PID %s: %s"
 
-#: dnsmasq.c:1369
+#: dnsmasq.c:1415
 #, fuzzy, c-format
 msgid "cannot open log %s: %s"
 msgstr "no se puede abrir registro %s: %s"
 
-#: dnsmasq.c:1373
+#: dnsmasq.c:1419
 #, fuzzy, c-format
 msgid "failed to load Lua script: %s"
 msgstr "no se pudo cargar script Lua %s: %s"
 
-#: dnsmasq.c:1377
+#: dnsmasq.c:1423
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr "directorio TFTP % inaccesible: %s"
 
-#: dnsmasq.c:1381
+#: dnsmasq.c:1427
 #, fuzzy, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "no se puede abrir o crear archivo de concesión %s: %s"
 
-#: dnsmasq.c:1465
+#: dnsmasq.c:1511
 #, fuzzy, c-format
 msgid "script process killed by signal %d"
 msgstr "proceso script eliminado por señal %d"
 
-#: dnsmasq.c:1469
+#: dnsmasq.c:1515
 #, fuzzy, c-format
 msgid "script process exited with status %d"
 msgstr "proceso script salió con con estado %d"
 
-#: dnsmasq.c:1473
+#: dnsmasq.c:1519
 #, fuzzy, c-format
 msgid "failed to execute %s: %s"
 msgstr "no se pudo ejecutar %s: %s"
 
-#: dnsmasq.c:1513
+#: dnsmasq.c:1559
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
+#: dnsmasq.c:1594 dnssec.c:160 dnssec.c:204
 #, fuzzy, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "no se pudo abrir archivo PID %s: %s"
 
-#: dnsmasq.c:1560
+#: dnsmasq.c:1606
 msgid "exiting on receipt of SIGTERM"
 msgstr "saliendo al recibir SIGTERM"
 
-#: dnsmasq.c:1588
+#: dnsmasq.c:1634
 #, fuzzy, c-format
 msgid "failed to access %s: %s"
 msgstr "no se pudo acceder %s: %s"
 
-#: dnsmasq.c:1618
+#: dnsmasq.c:1664
 #, c-format
 msgid "reading %s"
 msgstr "leyendo %s"
 
-#: dnsmasq.c:1629
+#: dnsmasq.c:1675
 #, fuzzy, c-format
 msgid "no servers found in %s, will retry"
 msgstr "ningún servidor encontrado en %s, se reintentará"
@@ -1794,27 +1905,27 @@ msgstr "Paquete DHCP recibido en %s que no tiene direcci
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:471
+#: dhcp.c:473
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:526
+#: dhcp.c:530
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "rango DHCP %s -- %s no coincide con máscara de subred %s"
 
-#: dhcp.c:914
+#: dhcp.c:918
 #, fuzzy, c-format
 msgid "bad line at %s line %d"
 msgstr "línea errónea en %s línea %d"
 
-#: dhcp.c:957
+#: dhcp.c:961
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr "ignorando %s línea %d, nombre o dirección IP duplicada"
 
-#: dhcp.c:1100 rfc3315.c:2139
+#: dhcp.c:1105 rfc3315.c:2182
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr "DHCP relay %s -> %s"
@@ -1860,7 +1971,7 @@ msgstr "archivo gui
 
 #: lease.c:381
 #, fuzzy, c-format
-msgid "failed to write %s: %s (retry in %us)"
+msgid "failed to write %s: %s (retry in %u s)"
 msgstr "error al escribir %s: %s (reintentar en %us)"
 
 #: lease.c:955
@@ -1868,203 +1979,203 @@ msgstr "error al escribir %s: %s (reintentar en %us)"
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr "Ignorando dominio %s para nombre de host DHCP %s"
 
-#: rfc2131.c:372
-#, c-format
-msgid "no address range available for DHCP request %s %s"
-msgstr "ningún rango de direcciónes disponible para pedido DHCP %s %s"
-
-#: rfc2131.c:373
+#: rfc2131.c:378
 msgid "with subnet selector"
 msgstr "con selector de subred"
 
-#: rfc2131.c:373
+#: rfc2131.c:383
 msgid "via"
 msgstr "vía"
 
-#: rfc2131.c:385
+#: rfc2131.c:389
+#, c-format
+msgid "no address range available for DHCP request %s %s"
+msgstr "ningún rango de direcciónes disponible para pedido DHCP %s %s"
+
+#: rfc2131.c:403
 #, fuzzy, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "%u Subred DHCP disponible: %s/%s"
 
-#: rfc2131.c:388 rfc3315.c:319
+#: rfc2131.c:409 rfc3315.c:319
 #, fuzzy, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr "%u Rango DHCP disponible: %s -- %s"
 
-#: rfc2131.c:499
+#: rfc2131.c:521
 #, fuzzy, c-format
 msgid "%u vendor class: %s"
 msgstr "%u Clase de vendedor: %s"
 
-#: rfc2131.c:501
+#: rfc2131.c:523
 #, fuzzy, c-format
 msgid "%u user class: %s"
 msgstr "%u Clase de usuario: %s"
 
-#: rfc2131.c:535
+#: rfc2131.c:557
 msgid "disabled"
 msgstr "deshabilitado"
 
-#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
-#: rfc3315.c:1097
+#: rfc2131.c:598 rfc2131.c:1087 rfc2131.c:1532 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1121
 msgid "ignored"
 msgstr "ignorado"
 
-#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
+#: rfc2131.c:613 rfc2131.c:1333 rfc3315.c:867
 msgid "address in use"
 msgstr "dirección en uso"
 
-#: rfc2131.c:605 rfc2131.c:1119
+#: rfc2131.c:627 rfc2131.c:1141
 msgid "no address available"
 msgstr "ninguna dirección disponible"
 
-#: rfc2131.c:612 rfc2131.c:1273
+#: rfc2131.c:634 rfc2131.c:1295
 msgid "wrong network"
 msgstr "red equivocada"
 
-#: rfc2131.c:627
+#: rfc2131.c:649
 msgid "no address configured"
 msgstr "ninguna dirección configurada"
 
-#: rfc2131.c:633 rfc2131.c:1323
+#: rfc2131.c:655 rfc2131.c:1346
 msgid "no leases left"
 msgstr "no sobra ninguna concesión"
 
-#: rfc2131.c:734 rfc3315.c:499
+#: rfc2131.c:756 rfc3315.c:499
 #, fuzzy, c-format
 msgid "%u client provides name: %s"
 msgstr "%u cliente provee nombre: %s"
 
-#: rfc2131.c:864
+#: rfc2131.c:885
 msgid "PXE BIS not supported"
 msgstr "no hay soporte para BIS PXE"
 
-#: rfc2131.c:1032 rfc3315.c:1197
+#: rfc2131.c:1054 rfc3315.c:1222
 #, fuzzy, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "deshabilitando dirección DHCP estática %s para %s"
 
-#: rfc2131.c:1053
+#: rfc2131.c:1075
 msgid "unknown lease"
 msgstr "concesión desconocida"
 
-#: rfc2131.c:1088
+#: rfc2131.c:1110
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr "no usando dirección configurada %s porque está concedida a %s"
 
-#: rfc2131.c:1098
+#: rfc2131.c:1120
 #, fuzzy, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr "no usando dirección configurada %s porque está en uso por el servidor o relay"
 
-#: rfc2131.c:1101
+#: rfc2131.c:1123
 #, fuzzy, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr "no usando dirección configurada %s porque fué previamente denegada"
 
-#: rfc2131.c:1117 rfc2131.c:1316
+#: rfc2131.c:1139 rfc2131.c:1339
 msgid "no unique-id"
 msgstr "ningún unique-id (identificación única)"
 
-#: rfc2131.c:1209
+#: rfc2131.c:1231
 msgid "wrong server-ID"
 msgstr "ID de servidor equivocada"
 
-#: rfc2131.c:1228
+#: rfc2131.c:1250
 msgid "wrong address"
 msgstr "dirección equivocada"
 
-#: rfc2131.c:1246 rfc3315.c:961
+#: rfc2131.c:1268 rfc3315.c:975
 msgid "lease not found"
 msgstr "concesión no encontrada"
 
-#: rfc2131.c:1281
+#: rfc2131.c:1303
 msgid "address not available"
 msgstr "dirección no disponible"
 
-#: rfc2131.c:1292
+#: rfc2131.c:1314
 msgid "static lease available"
 msgstr "concesión estática disponible"
 
-#: rfc2131.c:1296
+#: rfc2131.c:1318
 msgid "address reserved"
 msgstr "dirección reservada"
 
-#: rfc2131.c:1304
+#: rfc2131.c:1327
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr "abandonando concesión a %s de %s"
 
-#: rfc2131.c:1845
+#: rfc2131.c:1866
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr "%u nombre de bootfile: %s"
 
-#: rfc2131.c:1854
+#: rfc2131.c:1875
 #, c-format
 msgid "%u server name: %s"
 msgstr "%u nombre de servidor: %s"
 
-#: rfc2131.c:1862
+#: rfc2131.c:1885
 #, fuzzy, c-format
 msgid "%u next server: %s"
 msgstr "%u siguiente servidor: %s"
 
-#: rfc2131.c:1865
+#: rfc2131.c:1889
 #, c-format
 msgid "%u broadcast response"
 msgstr "%u respuesta broadcast"
 
-#: rfc2131.c:1928
+#: rfc2131.c:1952
 #, fuzzy, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "no se puede enviar opción DHCP/BOOTP %d: no queda espacio en el paquete"
 
-#: rfc2131.c:2219
+#: rfc2131.c:2262
 msgid "PXE menu too large"
 msgstr "menú PXE demasiado largo"
 
-#: rfc2131.c:2358 rfc3315.c:1470
+#: rfc2131.c:2425 rfc3315.c:1511
 #, fuzzy, c-format
 msgid "%u requested options: %s"
 msgstr "%u opciones solicitadas: %s"
 
-#: rfc2131.c:2675
+#: rfc2131.c:2742
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr "no se puede enviar opción RFC3925: demasiadas opciones para número enterprise %d"
 
-#: rfc2131.c:2738
+#: rfc2131.c:2805
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:76
+#: netlink.c:93
 #, fuzzy, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "no se puede crear zócalo netlink: %s"
 
-#: netlink.c:352
+#: netlink.c:377
 #, fuzzy, c-format
 msgid "netlink returns error: %s"
 msgstr "netlink retorna error: %s"
 
-#: dbus.c:438
+#: dbus.c:434
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:443
+#: dbus.c:439
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:717
+#: dbus.c:713
 msgid "setting upstream servers from DBus"
 msgstr "fijando servidores subida desde DBus"
 
-#: dbus.c:764
+#: dbus.c:760
 msgid "could not register a DBus message handler"
 msgstr "no se pudo registrar un manejador de mensajes DBus"
 
@@ -2091,31 +2202,36 @@ msgstr ""
 msgid "lease() function missing in Lua script"
 msgstr "la función lease() no se encuentra en el script Lua"
 
-#: tftp.c:347
+#: tftp.c:349
 msgid "unable to get free port for TFTP"
 msgstr "incapaz de conseguir puerto libre para TFTP"
 
-#: tftp.c:363
+#: tftp.c:365
 #, c-format
 msgid "unsupported request from %s"
 msgstr "pedido no-soportado desde %s"
 
-#: tftp.c:510
+#: tftp.c:512
 #, fuzzy, c-format
 msgid "file %s not found"
 msgstr "archivo %s no encontrado"
 
-#: tftp.c:628
+#: tftp.c:602
+#, c-format
+msgid "ignoring packet from %s (TID mismatch)"
+msgstr ""
+
+#: tftp.c:646
 #, fuzzy, c-format
 msgid "failed sending %s to %s"
 msgstr "TFTP no pudo enviar %s a %s"
 
-#: tftp.c:628
+#: tftp.c:646
 #, fuzzy, c-format
 msgid "sent %s to %s"
 msgstr "TFTP envió %s a %s"
 
-#: tftp.c:678
+#: tftp.c:696
 #, fuzzy, c-format
 msgid "error %d %s received from %s"
 msgstr "error TFTP %d %s recibido de %s"
@@ -2130,7 +2246,7 @@ msgstr "desbordamiento: %d entradas de registro perdidas"
 msgid "log failed: %s"
 msgstr "registro falló: %s"
 
-#: log.c:471
+#: log.c:477
 msgid "FAILED to start up"
 msgstr "el inicio ha FALLADO"
 
@@ -2184,11 +2300,11 @@ msgstr "%u cliente provee nombre: %s"
 msgid "address unavailable"
 msgstr "dirección no disponible"
 
-#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1272
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913 rfc3315.c:1047
 #, fuzzy
 msgid "no addresses available"
 msgstr "ninguna dirección disponible"
@@ -2197,116 +2313,116 @@ msgstr "ninguna direcci
 msgid "not on link"
 msgstr "no en el enlace"
 
-#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
+#: rfc3315.c:979 rfc3315.c:1180 rfc3315.c:1261
 msgid "no binding found"
 msgstr "uniones no encontradas"
 
-#: rfc3315.c:1002
+#: rfc3315.c:1016
 msgid "deprecated"
 msgstr "descartado"
 
-#: rfc3315.c:1007
+#: rfc3315.c:1023
 #, fuzzy
 msgid "address invalid"
 msgstr "dirección en uso"
 
-#: rfc3315.c:1057 rfc3315.c:1059
+#: rfc3315.c:1081 rfc3315.c:1083
 msgid "confirm failed"
 msgstr "confirmación falló"
 
-#: rfc3315.c:1074
+#: rfc3315.c:1098
 #, fuzzy
 msgid "all addresses still on link"
 msgstr "dirección errónea en %s línea %d"
 
-#: rfc3315.c:1165
+#: rfc3315.c:1189
 msgid "release received"
 msgstr "concesión recibida"
 
-#: rfc3315.c:2130
+#: rfc3315.c:2173
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr "No puede hacer multicast DHCPv6 sin el interfase correcto"
 
-#: dhcp-common.c:145
+#: dhcp-common.c:154
 #, c-format
 msgid "Ignoring duplicate dhcp-option %d"
 msgstr "Ignorando opción DHCP duplicada"
 
-#: dhcp-common.c:222
+#: dhcp-common.c:231
 #, c-format
 msgid "%u tags: %s"
 msgstr "%u etiquetas: %s"
 
-#: dhcp-common.c:444
+#: dhcp-common.c:451
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr "%s tiene más de una dirección en hostsfile, usando %s para DHCP"
 
-#: dhcp-common.c:478
+#: dhcp-common.c:485
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "dirección IP duplicada %s (%s) en directiva dhcp-config"
 
-#: dhcp-common.c:542
+#: dhcp-common.c:549
 #, fuzzy, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "no se pudo fijar SO_REUSE{ADDR|PORT} en socket DHCP: %s"
 
-#: dhcp-common.c:665
+#: dhcp-common.c:672
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr "Opciones DHCP conocidas:\n"
 
-#: dhcp-common.c:676
+#: dhcp-common.c:683
 #, fuzzy, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr "Opciones DHCP conocidas:\n"
 
-#: dhcp-common.c:873
+#: dhcp-common.c:880
 msgid ", prefix deprecated"
 msgstr ", prefijo descartado"
 
-#: dhcp-common.c:876
+#: dhcp-common.c:883
 #, c-format
 msgid ", lease time "
 msgstr ", tiempo de concesión"
 
-#: dhcp-common.c:918
+#: dhcp-common.c:925
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr "%s apátrida en %s%.0s%.0s%s"
 
-#: dhcp-common.c:920
+#: dhcp-common.c:927
 #, fuzzy, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "DHCP, concesión estática solo en %.0s%s, tiempo de concesión %s"
 
-#: dhcp-common.c:922
+#: dhcp-common.c:929
 #, fuzzy, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr "DHCP, proxy en subred %.0s%s%.0s"
 
-#: dhcp-common.c:923
+#: dhcp-common.c:930
 #, fuzzy, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "DHCP, rango de IPs %s -- %s, tiempo de concesión %s"
 
-#: dhcp-common.c:936
+#: dhcp-common.c:943
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:939
+#: dhcp-common.c:946
 #, fuzzy, c-format
 msgid "router advertisement on %s%s"
 msgstr "DHCP, concesión estáticos solo en %.0s%s, tiempo de concesión %s"
 
-#: dhcp-common.c:950
+#: dhcp-common.c:957
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:952
+#: dhcp-common.c:959
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2316,31 +2432,119 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "no se puede crear socket DHCP: %s"
 
-#: auth.c:439
+#: auth.c:464
 #, fuzzy, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr "pedido no-soportado desde %s"
 
-#: ipset.c:95
-#, fuzzy, c-format
-msgid "failed to find kernel version: %s"
-msgstr "no se pudo acoplar socket de servidor DHCP: %s"
-
-#: ipset.c:114
+#: ipset.c:99
 #, fuzzy, c-format
 msgid "failed to create IPset control socket: %s"
 msgstr "no se pudo crear socket TFTP: %s"
 
-#: ipset.c:226
+#: ipset.c:211
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "no se pudo abrir archivo PID %s: %s"
 
+#: pattern.c:29
+#, c-format
+msgid "[pattern.c:%d] Assertion failure: %s"
+msgstr ""
+
+#: pattern.c:142
+#, c-format
+msgid "Invalid DNS name: Invalid character %c."
+msgstr ""
+
+#: pattern.c:151
+msgid "Invalid DNS name: Empty label."
+msgstr ""
+
+#: pattern.c:156
+msgid "Invalid DNS name: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:170
+msgid "Invalid DNS name: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:176
+#, c-format
+msgid "Invalid DNS name: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:184
+#, c-format
+msgid "Invalid DNS name: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:189
+msgid "Invalid DNS name: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:199
+msgid "Invalid DNS name: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:204
+#, c-format
+msgid "DNS name has invalid length (%zu)."
+msgstr ""
+
+#: pattern.c:258
+#, c-format
+msgid "Invalid DNS name pattern: Invalid character %c."
+msgstr ""
+
+#: pattern.c:267
+msgid "Invalid DNS name pattern: Empty label."
+msgstr ""
+
+#: pattern.c:272
+msgid "Invalid DNS name pattern: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:285
+msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+msgstr ""
+
+#: pattern.c:295
+msgid "Invalid DNS name pattern: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:301
+#, c-format
+msgid "Invalid DNS name pattern: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:309
+#, c-format
+msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:314
+msgid "Invalid DNS name pattern: Wildcard within final two labels."
+msgstr ""
+
+#: pattern.c:319
+msgid "Invalid DNS name pattern: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:329
+msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:334
+#, c-format
+msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
+msgstr ""
+
 #: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: dnssec.c:902
+#: dnssec.c:1014
 #, c-format
 msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
 msgstr ""
@@ -2372,7 +2576,7 @@ msgstr ""
 
 #: tables.c:101
 #, fuzzy, c-format
-msgid "IPset: error:%s"
+msgid "IPset: error: %s"
 msgstr "error DBus: %s"
 
 #: tables.c:108
@@ -2434,56 +2638,54 @@ msgstr "no se puede leer %s: %s"
 msgid "bad header in %s"
 msgstr "dirección en uso"
 
-#: dump.c:201
+#: dump.c:205
 #, fuzzy
 msgid "failed to write packet dump"
 msgstr "no se pudo escuchar en socket: %s"
 
-#: dump.c:203
+#: dump.c:207
 #, c-format
 msgid "dumping UDP packet %u mask 0x%04x"
 msgstr ""
 
-#: ubus.c:52
+#: ubus.c:79
 #, c-format
 msgid "UBus subscription callback: %s subscriber(s)"
 msgstr ""
 
-#: ubus.c:73
+#: ubus.c:99
 #, fuzzy, c-format
 msgid "Cannot reconnect to UBus: %s"
 msgstr "no se puede abrir registro %s: %s"
 
-#: ubus.c:89
-msgid "Cannot initialize UBus: connection failed"
-msgstr ""
-
-#: ubus.c:102
-#, fuzzy, c-format
-msgid "Cannot add object to UBus: %s"
-msgstr "no se puede abrir registro %s: %s"
-
-#: ubus.c:112
-#, fuzzy
-msgid "Connected to system UBus"
-msgstr "conectado a DBus de sistema"
-
-#: ubus.c:122
+#: ubus.c:135
 msgid "Cannot set UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:142
+#: ubus.c:155
 msgid "Cannot poll UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:155
+#: ubus.c:168
 msgid "Disconnecting from UBus"
 msgstr ""
 
-#: ubus.c:199
-#, fuzzy, c-format
-msgid "Failed to send UBus event: %s"
-msgstr "no se pudo escuchar en socket: %s"
+#: ubus.c:179 ubus.c:326
+#, c-format
+msgid "UBus command failed: %d (%s)"
+msgstr ""
+
+#: hash-questions.c:40
+msgid "Failed to create SHA-256 hash object"
+msgstr ""
+
+#, fuzzy
+#~ msgid "Cannot add object to UBus: %s"
+#~ msgstr "no se puede abrir registro %s: %s"
+
+#, fuzzy
+#~ msgid "Failed to send UBus event: %s"
+#~ msgstr "no se pudo escuchar en socket: %s"
 
 #~ msgid "Specify DHCPv6 prefix class"
 #~ msgstr "Especificar prefijo de clase DHCPv6"
index f5cac78..f414461 100644 (file)
--- a/po/fi.po
+++ b/po/fi.po
@@ -16,1650 +16,1753 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: cache.c:559
+#: cache.c:572
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:1081
+#: cache.c:1094
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr ""
 
-#: cache.c:1103 dhcp.c:927
+#: cache.c:1116 dhcp.c:931
 #, c-format
 msgid "bad address at %s line %d"
 msgstr ""
 
-#: cache.c:1156 dhcp.c:943
+#: cache.c:1169 dhcp.c:947
 #, c-format
 msgid "bad name at %s line %d"
 msgstr ""
 
-#: cache.c:1167 dhcp.c:1018
+#: cache.c:1180 dhcp.c:1022
 #, c-format
 msgid "read %s - %d addresses"
 msgstr ""
 
-#: cache.c:1283
+#: cache.c:1296
 msgid "cleared cache"
 msgstr ""
 
-#: cache.c:1345
+#: cache.c:1358
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1391
+#: cache.c:1404
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
-#: cache.c:1415
+#: cache.c:1428
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr ""
 
-#: cache.c:1663
+#: cache.c:1674
 #, c-format
 msgid "time %lu"
 msgstr ""
 
-#: cache.c:1664
+#: cache.c:1675
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr ""
 
-#: cache.c:1666
+#: cache.c:1677
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1669
+#: cache.c:1680
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1694
+#: cache.c:1702
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
 
-#: util.c:47
+#: util.c:51
 #, c-format
 msgid "failed to seed the random number generator: %s"
 msgstr ""
 
-#: util.c:224
+#: util.c:228
 msgid "failed to allocate memory"
 msgstr ""
 
-#: util.c:281 option.c:641
+#: util.c:285 option.c:665
 msgid "could not get memory"
 msgstr ""
 
-#: util.c:302
+#: util.c:306
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr ""
 
-#: util.c:310
+#: util.c:314
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr ""
 
-#: util.c:506
+#: util.c:520
 #, c-format
 msgid "infinite"
 msgstr ""
 
-#: option.c:358
+#: util.c:808
+#, c-format
+msgid "failed to find kernel version: %s"
+msgstr ""
+
+#: option.c:372
 msgid "Specify local address(es) to listen on."
 msgstr ""
 
-#: option.c:359
+#: option.c:373
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr ""
 
-#: option.c:360
+#: option.c:374
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr ""
 
-#: option.c:361
+#: option.c:375
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr ""
 
-#: option.c:362
+#: option.c:376
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr ""
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr ""
 
-#: option.c:364
+#: option.c:378
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr ""
 
-#: option.c:365
+#: option.c:379
 msgid "Do NOT forward queries with no domain part."
 msgstr ""
 
-#: option.c:366
+#: option.c:380
 msgid "Return self-pointing MX records for local hosts."
 msgstr ""
 
-#: option.c:367
+#: option.c:381
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr ""
 
-#: option.c:368
+#: option.c:382
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr ""
 
-#: option.c:369
+#: option.c:383
 msgid "Enable DHCP in the range given with lease duration."
 msgstr ""
 
-#: option.c:370
+#: option.c:384
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr ""
 
-#: option.c:371
+#: option.c:385
 msgid "Set address or hostname for a specified machine."
 msgstr ""
 
-#: option.c:372
+#: option.c:386
 msgid "Read DHCP host specs from file."
 msgstr ""
 
-#: option.c:373
+#: option.c:387
 msgid "Read DHCP option specs from file."
 msgstr ""
 
-#: option.c:374
+#: option.c:388
 msgid "Read DHCP host specs from a directory."
 msgstr ""
 
-#: option.c:375
+#: option.c:389
 msgid "Read DHCP options from a directory."
 msgstr ""
 
-#: option.c:376
+#: option.c:390
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
-#: option.c:377
+#: option.c:391
 #, c-format
 msgid "Do NOT load %s file."
 msgstr ""
 
-#: option.c:378
+#: option.c:392
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr ""
 
-#: option.c:379
+#: option.c:393
 msgid "Read hosts files from a directory."
 msgstr ""
 
-#: option.c:380
+#: option.c:394
 msgid "Specify interface(s) to listen on."
 msgstr ""
 
-#: option.c:381
+#: option.c:395
 msgid "Specify interface(s) NOT to listen on."
 msgstr ""
 
-#: option.c:382
+#: option.c:396
 msgid "Map DHCP user class to tag."
 msgstr ""
 
-#: option.c:383
+#: option.c:397
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:384
+#: option.c:398
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
-#: option.c:386
+#: option.c:400
+msgid "Specify vendor class to match for PXE requests."
+msgstr ""
+
+#: option.c:401
 msgid "Don't do DHCP for hosts with tag set."
 msgstr ""
 
-#: option.c:387
+#: option.c:402
 msgid "Force broadcast replies for hosts with tag set."
 msgstr ""
 
-#: option.c:388
+#: option.c:403
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr ""
 
-#: option.c:389
+#: option.c:404
 msgid "Assume we are the only DHCP server on the local network."
 msgstr ""
 
-#: option.c:390
+#: option.c:405
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:391
+#: option.c:406
 msgid "Return MX records for local hosts."
 msgstr ""
 
-#: option.c:392
+#: option.c:407
 msgid "Specify an MX record."
 msgstr ""
 
-#: option.c:393
+#: option.c:408
 msgid "Specify BOOTP options to DHCP server."
 msgstr ""
 
-#: option.c:394
+#: option.c:409
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr ""
 
-#: option.c:395
+#: option.c:410
 msgid "Do NOT cache failed search results."
 msgstr ""
 
-#: option.c:396
+#: option.c:411
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr ""
 
-#: option.c:397
+#: option.c:412
 msgid "Specify options to be sent to DHCP clients."
 msgstr ""
 
-#: option.c:398
+#: option.c:413
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
-#: option.c:399
+#: option.c:414
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr ""
 
-#: option.c:400
+#: option.c:415
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr ""
 
-#: option.c:401
+#: option.c:416
 msgid "Log DNS queries."
 msgstr ""
 
-#: option.c:402
+#: option.c:417
 msgid "Force the originating port for upstream DNS queries."
 msgstr ""
 
-#: option.c:403
+#: option.c:418
 msgid "Do NOT read resolv.conf."
 msgstr ""
 
-#: option.c:404
+#: option.c:419
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr ""
 
-#: option.c:405
+#: option.c:420
 msgid "Specify path to file with server= options"
 msgstr ""
 
-#: option.c:406
+#: option.c:421
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr ""
 
-#: option.c:407
+#: option.c:422
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr ""
 
-#: option.c:408
+#: option.c:423
 msgid "Never forward queries to specified domains."
 msgstr ""
 
-#: option.c:409
+#: option.c:424
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr ""
 
-#: option.c:410
+#: option.c:425
 msgid "Specify default target in an MX record."
 msgstr ""
 
-#: option.c:411
+#: option.c:426
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr ""
 
-#: option.c:412
+#: option.c:427
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr ""
 
-#: option.c:413
+#: option.c:428
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr ""
 
-#: option.c:414
+#: option.c:429
 msgid "Specify time-to-live ceiling for cache."
 msgstr ""
 
-#: option.c:415
+#: option.c:430
 msgid "Specify time-to-live floor for cache."
 msgstr ""
 
-#: option.c:416
+#: option.c:431
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr ""
 
-#: option.c:417
+#: option.c:432
 msgid "Map DHCP vendor class to tag."
 msgstr ""
 
-#: option.c:418
+#: option.c:433
 msgid "Display dnsmasq version and copyright information."
 msgstr ""
 
-#: option.c:419
+#: option.c:434
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr ""
 
-#: option.c:420
+#: option.c:435
 msgid "Specify a SRV record."
 msgstr ""
 
-#: option.c:421
+#: option.c:436
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
-#: option.c:422
+#: option.c:437
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr ""
 
-#: option.c:423
+#: option.c:438
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:424
+#: option.c:439
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr ""
 
-#: option.c:425
+#: option.c:440
 msgid "Specify TXT DNS record."
 msgstr ""
 
-#: option.c:426
+#: option.c:441
 msgid "Specify PTR DNS record."
 msgstr ""
 
-#: option.c:427
+#: option.c:442
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
-#: option.c:428
+#: option.c:443
 msgid "Bind only to interfaces in use."
 msgstr ""
 
-#: option.c:429
+#: option.c:444
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr ""
 
-#: option.c:430
+#: option.c:445
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr ""
 
-#: option.c:431
+#: option.c:446
 msgid "Enable the UBus interface."
 msgstr ""
 
-#: option.c:432
+#: option.c:447
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr ""
 
-#: option.c:433
+#: option.c:448
 msgid "Enable dynamic address allocation for bootp."
 msgstr ""
 
-#: option.c:434
+#: option.c:449
 msgid "Map MAC address (with wildcards) to option set."
 msgstr ""
 
-#: option.c:435
+#: option.c:450
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:436
+#: option.c:451
 msgid "Specify extra networks sharing a broadcast domain for DHCP"
 msgstr ""
 
-#: option.c:437
+#: option.c:452
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:438
+#: option.c:453
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:439
+#: option.c:454
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:440
+#: option.c:455
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:441
+#: option.c:456
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:442
+#: option.c:457
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
-#: option.c:443
+#: option.c:458
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr ""
 
-#: option.c:444
+#: option.c:459
 msgid "Do not use leasefile."
 msgstr ""
 
-#: option.c:445
+#: option.c:460
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr ""
 
-#: option.c:446
+#: option.c:461
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:447
+#: option.c:462
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:448
+#: option.c:463
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:449
+#: option.c:464
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:450
+#: option.c:465
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:451
+#: option.c:466
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:452
+#: option.c:467
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:453
+#: option.c:468
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:454
+#: option.c:469
 #, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr ""
 
-#: option.c:455
+#: option.c:470
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr ""
 
-#: option.c:456
+#: option.c:471
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:457
+#: option.c:472
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:458
+#: option.c:473
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:459
+#: option.c:474
 msgid "Use only one port for TFTP server."
 msgstr ""
 
-#: option.c:460
+#: option.c:475
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:461
+#: option.c:476
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:462
+#: option.c:477
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:463
+#: option.c:478
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:464
+#: option.c:479
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:465
+#: option.c:480
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:466
+#: option.c:481
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:467
+#: option.c:482
 msgid "Set tag if client provides given name."
 msgstr ""
 
-#: option.c:468
+#: option.c:483
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
-#: option.c:469
+#: option.c:484
 msgid "Specify NAPTR DNS record."
 msgstr ""
 
-#: option.c:470
+#: option.c:485
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:471
+#: option.c:486
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:472
+#: option.c:487
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:473
+#: option.c:488
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:474
+#: option.c:489
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:475
+#: option.c:490
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:476
+#: option.c:491
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
-#: option.c:477
+#: option.c:492
 msgid "Prompt to send to PXE clients."
 msgstr ""
 
-#: option.c:478
+#: option.c:493
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:479
+#: option.c:494
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:480
+#: option.c:495
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:481
+#: option.c:496
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
-#: option.c:482
+#: option.c:497
 msgid "Add client identification to forwarded DNS queries."
 msgstr ""
 
-#: option.c:483
+#: option.c:498
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr ""
 
-#: option.c:484
+#: option.c:499
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:485
+#: option.c:500
 msgid "Ignore client identifier option sent by DHCP clients."
 msgstr ""
 
-#: option.c:486
+#: option.c:501
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:487
+#: option.c:502
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:488
+#: option.c:503
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:489
+#: option.c:504
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:490
+#: option.c:505
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr ""
 
-#: option.c:491
+#: option.c:506
+msgid "Specify host record in interface subnet"
+msgstr ""
+
+#: option.c:507
 msgid "Specify certification authority authorization record"
 msgstr ""
 
-#: option.c:492
+#: option.c:508
 msgid "Specify arbitrary DNS resource record"
 msgstr ""
 
-#: option.c:493
+#: option.c:509
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr ""
 
-#: option.c:494
+#: option.c:510
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:495
+#: option.c:511
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:496
+#: option.c:512
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:497
+#: option.c:513
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:498
+#: option.c:514
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:499
+#: option.c:515
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:500
+#: option.c:516
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:501
+#: option.c:517
+msgid "Enable filtering of DNS queries with connection-track marks."
+msgstr ""
+
+#: option.c:518
+msgid "Set allowed DNS patterns for a connection-track mark."
+msgstr ""
+
+#: option.c:519
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:502
+#: option.c:520
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:503
+#: option.c:521
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:504
+#: option.c:522
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:505
+#: option.c:523
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:506
+#: option.c:524
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:507
+#: option.c:525
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:508
+#: option.c:526
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:509
+#: option.c:527
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:510
+#: option.c:528
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:511
+#: option.c:529
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:512
+#: option.c:530
+msgid "Log debugging information."
+msgstr ""
+
+#: option.c:531
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:513
+#: option.c:532
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:514
+#: option.c:533
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:515
+#: option.c:534
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:516
+#: option.c:535
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:517
+#: option.c:536
 msgid "Enables DHCPv4 Rapid Commit option."
 msgstr ""
 
-#: option.c:518
+#: option.c:537
 msgid "Path to debug packet dump file"
 msgstr ""
 
-#: option.c:519
+#: option.c:538
 msgid "Mask which packets to dump"
 msgstr ""
 
-#: option.c:520
+#: option.c:539
 msgid "Call dhcp-script when lease expiry changes."
 msgstr ""
 
-#: option.c:725
+#: option.c:540
+msgid "Send Cisco Umbrella identifiers including remote IP."
+msgstr ""
+
+#: option.c:541
+msgid "Do not log routine TFTP."
+msgstr ""
+
+#: option.c:771
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
 "\n"
 msgstr ""
 
-#: option.c:727
+#: option.c:773
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr ""
 
-#: option.c:729
+#: option.c:775
 #, c-format
 msgid "Valid options are:\n"
 msgstr ""
 
-#: option.c:776 option.c:884
+#: option.c:822 option.c:933
 msgid "bad address"
 msgstr ""
 
-#: option.c:799 option.c:803
+#: option.c:847 option.c:851
 msgid "bad port"
 msgstr ""
 
-#: option.c:815 option.c:844 option.c:878
+#: option.c:864 option.c:893 option.c:927
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:839 option.c:873
+#: option.c:888 option.c:922
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:852 option.c:4042
+#: option.c:901 option.c:4362
 msgid "bad interface name"
 msgstr ""
 
-#: option.c:1184
+#: option.c:1192
+msgid "inappropriate vendor:"
+msgstr ""
+
+#: option.c:1199
+msgid "inappropriate encap:"
+msgstr ""
+
+#: option.c:1225
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
-#: option.c:1198
+#: option.c:1239
 msgid "bad dhcp-option"
 msgstr ""
 
-#: option.c:1270
+#: option.c:1317
 msgid "bad IP address"
 msgstr ""
 
-#: option.c:1273 option.c:1412 option.c:3297
+#: option.c:1320 option.c:1459 option.c:3551
 msgid "bad IPv6 address"
 msgstr ""
 
-#: option.c:1366
+#: option.c:1413
 msgid "bad IPv4 address"
 msgstr ""
 
-#: option.c:1439 option.c:1533
+#: option.c:1486 option.c:1581
 msgid "bad domain in dhcp-option"
 msgstr ""
 
-#: option.c:1571
+#: option.c:1625
 msgid "dhcp-option too long"
 msgstr ""
 
-#: option.c:1578
+#: option.c:1632
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1647
+#: option.c:1691
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1655
+#: option.c:1699
 msgid "illegal repeated keyword"
 msgstr ""
 
-#: option.c:1726 option.c:4764
+#: option.c:1770 option.c:5080
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr ""
 
-#: option.c:1772 tftp.c:564 dump.c:68
+#: option.c:1816 tftp.c:566 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr ""
 
-#: option.c:1879
+#: option.c:1931
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1888
+#: option.c:1940
 msgid "bad log facility"
 msgstr ""
 
-#: option.c:1941
+#: option.c:1993
 msgid "bad MX preference"
 msgstr ""
 
-#: option.c:1946
+#: option.c:1998
 msgid "bad MX name"
 msgstr ""
 
-#: option.c:1960
+#: option.c:2012
 msgid "bad MX target"
 msgstr ""
 
-#: option.c:1980
+#: option.c:2032
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1984
+#: option.c:2036
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
-#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
+#: option.c:2291 option.c:2327
+msgid "bad prefix length"
+msgstr ""
+
+#: option.c:2303 option.c:2348 option.c:2398
 msgid "bad prefix"
 msgstr ""
 
-#: option.c:2658
+#: option.c:2418
+msgid "prefix length too small"
+msgstr ""
+
+#: option.c:2697
+msgid "Bad address in --address"
+msgstr ""
+
+#: option.c:2751
+msgid "bad IPv4 prefix"
+msgstr ""
+
+#: option.c:2756 option.c:3569
+msgid "bad IPv6 prefix"
+msgstr ""
+
+#: option.c:2777
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
-#: option.c:2871
+#: option.c:2843 option.c:2861
+msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+msgstr ""
+
+#: option.c:3119
 msgid "bad port range"
 msgstr ""
 
-#: option.c:2897
+#: option.c:3145
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2941
+#: option.c:3189
 msgid "bad shared-network"
 msgstr ""
 
-#: option.c:2996
+#: option.c:3243
 msgid "only one tag allowed"
 msgstr ""
 
-#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
+#: option.c:3264 option.c:3280 option.c:3406 option.c:3414 option.c:3457
 msgid "bad dhcp-range"
 msgstr ""
 
-#: option.c:3050
+#: option.c:3298
 msgid "inconsistent DHCP range"
 msgstr ""
 
-#: option.c:3115
+#: option.c:3364
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:3117
+#: option.c:3366
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:3120
+#: option.c:3369
 msgid "prefix length must be at least 64"
 msgstr ""
 
-#: option.c:3123
+#: option.c:3372
 msgid "inconsistent DHCPv6 range"
 msgstr ""
 
-#: option.c:3142
+#: option.c:3391
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
-#: option.c:3262 option.c:3340
+#: option.c:3516 option.c:3594
 msgid "bad hex constant"
 msgstr ""
 
-#: option.c:3315
-msgid "bad IPv6 prefix"
-msgstr ""
-
-#: option.c:3362
+#: option.c:3617
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr ""
 
-#: option.c:3422
+#: option.c:3678
 msgid "bad DHCP host name"
 msgstr ""
 
-#: option.c:3508
+#: option.c:3764
 msgid "bad tag-if"
 msgstr ""
 
-#: option.c:3851 option.c:4324
+#: option.c:4107 option.c:4623
 msgid "invalid port number"
 msgstr ""
 
-#: option.c:3907
+#: option.c:4163
 msgid "bad dhcp-proxy address"
 msgstr ""
 
-#: option.c:3935
+#: option.c:4204
 msgid "Bad dhcp-relay"
 msgstr ""
 
-#: option.c:3979
+#: option.c:4248
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3989
+#: option.c:4258
 msgid "bad DUID"
 msgstr ""
 
-#: option.c:4023
+#: option.c:4292
 msgid "missing address in alias"
 msgstr ""
 
-#: option.c:4029
+#: option.c:4298
 msgid "invalid alias range"
 msgstr ""
 
-#: option.c:4081 option.c:4097
+#: option.c:4347
+msgid "missing address in dynamic host"
+msgstr ""
+
+#: option.c:4362
+msgid "bad dynamic host"
+msgstr ""
+
+#: option.c:4380 option.c:4396
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:4105
+#: option.c:4404
 msgid "duplicate CNAME"
 msgstr ""
 
-#: option.c:4132
+#: option.c:4431
 msgid "bad PTR record"
 msgstr ""
 
-#: option.c:4167
+#: option.c:4466
 msgid "bad NAPTR record"
 msgstr ""
 
-#: option.c:4203
+#: option.c:4502
 msgid "bad RR record"
 msgstr ""
 
-#: option.c:4236
+#: option.c:4535
 msgid "bad CAA record"
 msgstr ""
 
-#: option.c:4265
+#: option.c:4564
 msgid "bad TXT record"
 msgstr ""
 
-#: option.c:4308
+#: option.c:4607
 msgid "bad SRV record"
 msgstr ""
 
-#: option.c:4315
+#: option.c:4614
 msgid "bad SRV target"
 msgstr ""
 
-#: option.c:4334
+#: option.c:4633
 msgid "invalid priority"
 msgstr ""
 
-#: option.c:4339
+#: option.c:4638
 msgid "invalid weight"
 msgstr ""
 
-#: option.c:4362
+#: option.c:4661
 msgid "Bad host-record"
 msgstr ""
 
-#: option.c:4402
+#: option.c:4700
 msgid "Bad name in host-record"
 msgstr ""
 
-#: option.c:4444
+#: option.c:4742
 msgid "bad value for dnssec-check-unsigned"
 msgstr ""
 
-#: option.c:4480
+#: option.c:4778
 msgid "bad trust anchor"
 msgstr ""
 
-#: option.c:4496
+#: option.c:4794
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4507
+#: option.c:4805
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
-#: option.c:4567
+#: option.c:4865
 msgid "missing \""
 msgstr ""
 
-#: option.c:4624
+#: option.c:4922
 msgid "bad option"
 msgstr ""
 
-#: option.c:4626
+#: option.c:4924
 msgid "extraneous parameter"
 msgstr ""
 
-#: option.c:4628
+#: option.c:4926
 msgid "missing parameter"
 msgstr ""
 
-#: option.c:4630
+#: option.c:4928
 msgid "illegal option"
 msgstr ""
 
-#: option.c:4637
+#: option.c:4935
 msgid "error"
 msgstr ""
 
-#: option.c:4639
+#: option.c:4937
 #, c-format
 msgid " at line %d of %s"
 msgstr ""
 
-#: option.c:4654 option.c:4939 option.c:4950
+#: option.c:4952 option.c:5229 option.c:5240
 #, c-format
 msgid "read %s"
 msgstr ""
 
-#: option.c:4717 option.c:4840 tftp.c:754
+#: option.c:5015 option.c:5162 tftp.c:775
 #, c-format
 msgid "cannot read %s: %s"
 msgstr ""
 
-#: option.c:5027
+#: option.c:5316
 msgid "junk found in command line"
 msgstr ""
 
-#: option.c:5067
+#: option.c:5356
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr ""
 
-#: option.c:5068
+#: option.c:5357
 #, c-format
 msgid ""
 "Compile time options: %s\n"
 "\n"
 msgstr ""
 
-#: option.c:5069
+#: option.c:5358
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr ""
 
-#: option.c:5070
+#: option.c:5359
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr ""
 
-#: option.c:5071
+#: option.c:5360
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr ""
 
-#: option.c:5088
+#: option.c:5377
 msgid "try --help"
 msgstr ""
 
-#: option.c:5090
+#: option.c:5379
 msgid "try -w"
 msgstr ""
 
-#: option.c:5092
+#: option.c:5381
 #, c-format
 msgid "bad command line options: %s"
 msgstr ""
 
-#: option.c:5161
+#: option.c:5450
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:5195
+#: option.c:5491
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr ""
 
-#: option.c:5223
+#: option.c:5519
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr ""
 
-#: option.c:5233
+#: option.c:5529
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr ""
 
-#: option.c:5236 network.c:1594 dhcp.c:876
+#: option.c:5532 network.c:1670 dhcp.c:880
 #, c-format
 msgid "failed to read %s: %s"
 msgstr ""
 
-#: option.c:5253
+#: option.c:5549
 #, c-format
 msgid "no search directive found in %s"
 msgstr ""
 
-#: option.c:5274
+#: option.c:5570
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:5283
+#: option.c:5579
 msgid "syntax check OK"
 msgstr ""
 
-#: forward.c:99
+#: forward.c:104
 #, c-format
 msgid "failed to send packet: %s"
 msgstr ""
 
-#: forward.c:614
+#: forward.c:601
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:677
+#: forward.c:666
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr ""
 
-#: forward.c:709
+#: forward.c:702
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:961
+#: forward.c:1074
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1370 forward.c:1830
+#: forward.c:1381 forward.c:1910
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2321
+#: forward.c:2198
+#, c-format
+msgid "failed to bind server socket to %s: %s"
+msgstr ""
+
+#: forward.c:2494
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr ""
 
-#: network.c:698
+#: forward.c:2496
+#, c-format
+msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+msgstr ""
+
+#: network.c:670
+#, c-format
+msgid "stopped listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:867
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr ""
 
-#: network.c:1002
+#: network.c:1148
+#, c-format
+msgid "listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:1175
+#, c-format
+msgid "listening on %s port %d"
+msgstr ""
+
+#: network.c:1208
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1009
+#: network.c:1215
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1018
+#: network.c:1224
 #, c-format
 msgid "warning: using interface %s instead"
 msgstr ""
 
-#: network.c:1027
+#: network.c:1233
 #, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr ""
 
-#: network.c:1085
+#: network.c:1291
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr ""
 
-#: network.c:1090
+#: network.c:1296
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1307
+#: network.c:1492
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr ""
 
-#: network.c:1499
+#: network.c:1569
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr ""
 
-#: network.c:1510
+#: network.c:1580
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr ""
 
-#: network.c:1530
+#: network.c:1598
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1533
+#: network.c:1601
 msgid "unqualified"
 msgstr ""
 
-#: network.c:1533
+#: network.c:1601
 msgid "names"
 msgstr ""
 
-#: network.c:1535
+#: network.c:1603
 msgid "default"
 msgstr ""
 
-#: network.c:1537
+#: network.c:1605
 msgid "domain"
 msgstr ""
 
-#: network.c:1543
+#: network.c:1607
 #, c-format
-msgid "using only locally-known addresses for %s %s"
+msgid "using nameserver %s#%d for %s %s%s %s"
 msgstr ""
 
-#: network.c:1546
+#: network.c:1611
 #, c-format
-msgid "using standard nameservers for %s %s"
+msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr ""
 
-#: network.c:1548
+#: network.c:1614
 #, c-format
-msgid "using nameserver %s#%d for %s %s %s"
+msgid "using nameserver %s#%d(via %s)"
 msgstr ""
 
-#: network.c:1552
+#: network.c:1616
 #, c-format
-msgid "NOT using nameserver %s#%d - query loop detected"
+msgid "using nameserver %s#%d"
 msgstr ""
 
-#: network.c:1555
+#: network.c:1630
 #, c-format
-msgid "using nameserver %s#%d(via %s)"
+msgid "using only locally-known addresses for %s"
 msgstr ""
 
-#: network.c:1557
+#: network.c:1633
 #, c-format
-msgid "using nameserver %s#%d"
+msgid "using standard nameservers for %s"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1637
 #, c-format
 msgid "using %d more local addresses"
 msgstr ""
 
-#: network.c:1564
+#: network.c:1639
 #, c-format
 msgid "using %d more nameservers"
 msgstr ""
 
-#: dnsmasq.c:173
+#: dnsmasq.c:184
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:188
+#: dnsmasq.c:199
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:202
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:193
+#: dnsmasq.c:204
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:199
+#: dnsmasq.c:210
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:204
+#: dnsmasq.c:217
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
-#: dnsmasq.c:207
+#: dnsmasq.c:223
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:212
+#: dnsmasq.c:228
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:217
+#: dnsmasq.c:233
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
-#: dnsmasq.c:222
+#: dnsmasq.c:238
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:227
+#: dnsmasq.c:243
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:232
+#: dnsmasq.c:248
 msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:236
+#: dnsmasq.c:259
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:243
+#: dnsmasq.c:266
 msgid "--auth-server required when an auth zone is defined."
 msgstr ""
 
-#: dnsmasq.c:248
+#: dnsmasq.c:271
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:268
+#: dnsmasq.c:291
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:332
+#: dnsmasq.c:355
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
-#: dnsmasq.c:335
+#: dnsmasq.c:358
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr ""
 
-#: dnsmasq.c:344
+#: dnsmasq.c:367
 #, c-format
 msgid "unknown interface %s"
 msgstr ""
 
-#: dnsmasq.c:406
+#: dnsmasq.c:437
 msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:416 dnsmasq.c:1171
+#: dnsmasq.c:445 dnsmasq.c:1207
 #, c-format
 msgid "DBus error: %s"
 msgstr ""
 
-#: dnsmasq.c:419
+#: dnsmasq.c:448
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:429
-msgid "UBus not available: set HAVE_UBUS in src/config.h"
+#: dnsmasq.c:456 dnsmasq.c:1228
+#, c-format
+msgid "UBus error: %s"
 msgstr ""
 
 #: dnsmasq.c:459
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr ""
+
+#: dnsmasq.c:489
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:535
+#: dnsmasq.c:565
 #, c-format
 msgid "process is missing required capability %s"
 msgstr ""
 
-#: dnsmasq.c:567
+#: dnsmasq.c:597
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
-#: dnsmasq.c:815
+#: dnsmasq.c:845
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr ""
 
-#: dnsmasq.c:820
+#: dnsmasq.c:850
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr ""
 
-#: dnsmasq.c:822
+#: dnsmasq.c:852
 msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
 msgstr ""
 
-#: dnsmasq.c:825
+#: dnsmasq.c:855
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr ""
 
-#: dnsmasq.c:828
+#: dnsmasq.c:858
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:831
+#: dnsmasq.c:861
 #, c-format
 msgid "compile time options: %s"
 msgstr ""
 
-#: dnsmasq.c:840
+#: dnsmasq.c:870
 msgid "DBus support enabled: connected to system bus"
 msgstr ""
 
-#: dnsmasq.c:842
+#: dnsmasq.c:872
 msgid "DBus support enabled: bus connection pending"
 msgstr ""
 
-#: dnsmasq.c:850
+#: dnsmasq.c:880
 msgid "UBus support enabled: connected to system bus"
 msgstr ""
 
-#: dnsmasq.c:852
+#: dnsmasq.c:882
 msgid "UBus support enabled: bus connection pending"
 msgstr ""
 
-#: dnsmasq.c:872
+#: dnsmasq.c:902
 msgid "DNSSEC validation enabled but all unsigned answers are trusted"
 msgstr ""
 
-#: dnsmasq.c:874
+#: dnsmasq.c:904
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:878
+#: dnsmasq.c:908
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:881
+#: dnsmasq.c:911
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:884
+#: dnsmasq.c:914
 #, c-format
 msgid "configured with trust anchor for %s keytag %u"
 msgstr ""
 
-#: dnsmasq.c:890
+#: dnsmasq.c:920
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr ""
 
-#: dnsmasq.c:894
+#: dnsmasq.c:924
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr ""
 
-#: dnsmasq.c:906
+#: dnsmasq.c:936
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr ""
 
-#: dnsmasq.c:911
+#: dnsmasq.c:941
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
-#: dnsmasq.c:914
+#: dnsmasq.c:944
 msgid "warning: no upstream servers configured"
 msgstr ""
 
-#: dnsmasq.c:918
+#: dnsmasq.c:948
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:939
+#: dnsmasq.c:969
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:944
+#: dnsmasq.c:974
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "root is "
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "enabled"
 msgstr ""
 
-#: dnsmasq.c:960
+#: dnsmasq.c:993
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:961
+#: dnsmasq.c:994
 msgid "single port mode"
 msgstr ""
 
-#: dnsmasq.c:964
+#: dnsmasq.c:997
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:968
+#: dnsmasq.c:1001
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:994
+#: dnsmasq.c:1027
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
-#: dnsmasq.c:1173
+#: dnsmasq.c:1204
 msgid "connected to system DBus"
 msgstr ""
 
-#: dnsmasq.c:1345
+#: dnsmasq.c:1225
+msgid "connected to system UBus"
+msgstr ""
+
+#: dnsmasq.c:1391
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
-#: dnsmasq.c:1349
+#: dnsmasq.c:1395
 #, c-format
 msgid "failed to create helper: %s"
 msgstr ""
 
-#: dnsmasq.c:1353
+#: dnsmasq.c:1399
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
-#: dnsmasq.c:1357
+#: dnsmasq.c:1403
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1361
+#: dnsmasq.c:1407
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1365
+#: dnsmasq.c:1411
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1369
+#: dnsmasq.c:1415
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1373
+#: dnsmasq.c:1419
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr ""
 
-#: dnsmasq.c:1377
+#: dnsmasq.c:1423
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
-#: dnsmasq.c:1381
+#: dnsmasq.c:1427
 #, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1465
+#: dnsmasq.c:1511
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1469
+#: dnsmasq.c:1515
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
-#: dnsmasq.c:1473
+#: dnsmasq.c:1519
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1513
+#: dnsmasq.c:1559
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
+#: dnsmasq.c:1594 dnssec.c:160 dnssec.c:204
 #, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1560
+#: dnsmasq.c:1606
 msgid "exiting on receipt of SIGTERM"
 msgstr ""
 
-#: dnsmasq.c:1588
+#: dnsmasq.c:1634
 #, c-format
 msgid "failed to access %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1618
+#: dnsmasq.c:1664
 #, c-format
 msgid "reading %s"
 msgstr ""
 
-#: dnsmasq.c:1629
+#: dnsmasq.c:1675
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr ""
@@ -1704,27 +1807,27 @@ msgstr ""
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:471
+#: dhcp.c:473
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:526
+#: dhcp.c:530
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr ""
 
-#: dhcp.c:914
+#: dhcp.c:918
 #, c-format
 msgid "bad line at %s line %d"
 msgstr ""
 
-#: dhcp.c:957
+#: dhcp.c:961
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1100 rfc3315.c:2139
+#: dhcp.c:1105 rfc3315.c:2182
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
@@ -1769,7 +1872,7 @@ msgstr ""
 
 #: lease.c:381
 #, c-format
-msgid "failed to write %s: %s (retry in %us)"
+msgid "failed to write %s: %s (retry in %u s)"
 msgstr ""
 
 #: lease.c:955
@@ -1777,203 +1880,203 @@ msgstr ""
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
-#: rfc2131.c:372
-#, c-format
-msgid "no address range available for DHCP request %s %s"
-msgstr ""
-
-#: rfc2131.c:373
+#: rfc2131.c:378
 msgid "with subnet selector"
 msgstr ""
 
-#: rfc2131.c:373
+#: rfc2131.c:383
 msgid "via"
 msgstr ""
 
-#: rfc2131.c:385
+#: rfc2131.c:389
+#, c-format
+msgid "no address range available for DHCP request %s %s"
+msgstr ""
+
+#: rfc2131.c:403
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr ""
 
-#: rfc2131.c:388 rfc3315.c:319
+#: rfc2131.c:409 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
-#: rfc2131.c:499
+#: rfc2131.c:521
 #, c-format
 msgid "%u vendor class: %s"
 msgstr ""
 
-#: rfc2131.c:501
+#: rfc2131.c:523
 #, c-format
 msgid "%u user class: %s"
 msgstr ""
 
-#: rfc2131.c:535
+#: rfc2131.c:557
 msgid "disabled"
 msgstr ""
 
-#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
-#: rfc3315.c:1097
+#: rfc2131.c:598 rfc2131.c:1087 rfc2131.c:1532 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1121
 msgid "ignored"
 msgstr ""
 
-#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
+#: rfc2131.c:613 rfc2131.c:1333 rfc3315.c:867
 msgid "address in use"
 msgstr ""
 
-#: rfc2131.c:605 rfc2131.c:1119
+#: rfc2131.c:627 rfc2131.c:1141
 msgid "no address available"
 msgstr ""
 
-#: rfc2131.c:612 rfc2131.c:1273
+#: rfc2131.c:634 rfc2131.c:1295
 msgid "wrong network"
 msgstr ""
 
-#: rfc2131.c:627
+#: rfc2131.c:649
 msgid "no address configured"
 msgstr ""
 
-#: rfc2131.c:633 rfc2131.c:1323
+#: rfc2131.c:655 rfc2131.c:1346
 msgid "no leases left"
 msgstr ""
 
-#: rfc2131.c:734 rfc3315.c:499
+#: rfc2131.c:756 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:864
+#: rfc2131.c:885
 msgid "PXE BIS not supported"
 msgstr ""
 
-#: rfc2131.c:1032 rfc3315.c:1197
+#: rfc2131.c:1054 rfc3315.c:1222
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr ""
 
-#: rfc2131.c:1053
+#: rfc2131.c:1075
 msgid "unknown lease"
 msgstr ""
 
-#: rfc2131.c:1088
+#: rfc2131.c:1110
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1098
+#: rfc2131.c:1120
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1101
+#: rfc2131.c:1123
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1117 rfc2131.c:1316
+#: rfc2131.c:1139 rfc2131.c:1339
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1209
+#: rfc2131.c:1231
 msgid "wrong server-ID"
 msgstr ""
 
-#: rfc2131.c:1228
+#: rfc2131.c:1250
 msgid "wrong address"
 msgstr ""
 
-#: rfc2131.c:1246 rfc3315.c:961
+#: rfc2131.c:1268 rfc3315.c:975
 msgid "lease not found"
 msgstr ""
 
-#: rfc2131.c:1281
+#: rfc2131.c:1303
 msgid "address not available"
 msgstr ""
 
-#: rfc2131.c:1292
+#: rfc2131.c:1314
 msgid "static lease available"
 msgstr ""
 
-#: rfc2131.c:1296
+#: rfc2131.c:1318
 msgid "address reserved"
 msgstr ""
 
-#: rfc2131.c:1304
+#: rfc2131.c:1327
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1845
+#: rfc2131.c:1866
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
-#: rfc2131.c:1854
+#: rfc2131.c:1875
 #, c-format
 msgid "%u server name: %s"
 msgstr ""
 
-#: rfc2131.c:1862
+#: rfc2131.c:1885
 #, c-format
 msgid "%u next server: %s"
 msgstr ""
 
-#: rfc2131.c:1865
+#: rfc2131.c:1889
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1928
+#: rfc2131.c:1952
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr ""
 
-#: rfc2131.c:2219
+#: rfc2131.c:2262
 msgid "PXE menu too large"
 msgstr ""
 
-#: rfc2131.c:2358 rfc3315.c:1470
+#: rfc2131.c:2425 rfc3315.c:1511
 #, c-format
 msgid "%u requested options: %s"
 msgstr ""
 
-#: rfc2131.c:2675
+#: rfc2131.c:2742
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2738
+#: rfc2131.c:2805
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:76
+#: netlink.c:93
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr ""
 
-#: netlink.c:352
+#: netlink.c:377
 #, c-format
 msgid "netlink returns error: %s"
 msgstr ""
 
-#: dbus.c:438
+#: dbus.c:434
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:443
+#: dbus.c:439
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:717
+#: dbus.c:713
 msgid "setting upstream servers from DBus"
 msgstr ""
 
-#: dbus.c:764
+#: dbus.c:760
 msgid "could not register a DBus message handler"
 msgstr ""
 
@@ -2000,31 +2103,36 @@ msgstr ""
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:347
+#: tftp.c:349
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:363
+#: tftp.c:365
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
-#: tftp.c:510
+#: tftp.c:512
 #, c-format
 msgid "file %s not found"
 msgstr ""
 
-#: tftp.c:628
+#: tftp.c:602
+#, c-format
+msgid "ignoring packet from %s (TID mismatch)"
+msgstr ""
+
+#: tftp.c:646
 #, c-format
 msgid "failed sending %s to %s"
 msgstr ""
 
-#: tftp.c:628
+#: tftp.c:646
 #, c-format
 msgid "sent %s to %s"
 msgstr ""
 
-#: tftp.c:678
+#: tftp.c:696
 #, c-format
 msgid "error %d %s received from %s"
 msgstr ""
@@ -2039,7 +2147,7 @@ msgstr ""
 msgid "log failed: %s"
 msgstr ""
 
-#: log.c:471
+#: log.c:477
 msgid "FAILED to start up"
 msgstr ""
 
@@ -2092,11 +2200,11 @@ msgstr ""
 msgid "address unavailable"
 msgstr ""
 
-#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1272
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913 rfc3315.c:1047
 msgid "no addresses available"
 msgstr ""
 
@@ -2104,114 +2212,114 @@ msgstr ""
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
+#: rfc3315.c:979 rfc3315.c:1180 rfc3315.c:1261
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1002
+#: rfc3315.c:1016
 msgid "deprecated"
 msgstr ""
 
-#: rfc3315.c:1007
+#: rfc3315.c:1023
 msgid "address invalid"
 msgstr ""
 
-#: rfc3315.c:1057 rfc3315.c:1059
+#: rfc3315.c:1081 rfc3315.c:1083
 msgid "confirm failed"
 msgstr ""
 
-#: rfc3315.c:1074
+#: rfc3315.c:1098
 msgid "all addresses still on link"
 msgstr ""
 
-#: rfc3315.c:1165
+#: rfc3315.c:1189
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2130
+#: rfc3315.c:2173
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
-#: dhcp-common.c:145
+#: dhcp-common.c:154
 #, c-format
 msgid "Ignoring duplicate dhcp-option %d"
 msgstr ""
 
-#: dhcp-common.c:222
+#: dhcp-common.c:231
 #, c-format
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:444
+#: dhcp-common.c:451
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
-#: dhcp-common.c:478
+#: dhcp-common.c:485
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr ""
 
-#: dhcp-common.c:542
+#: dhcp-common.c:549
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr ""
 
-#: dhcp-common.c:665
+#: dhcp-common.c:672
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:676
+#: dhcp-common.c:683
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:873
+#: dhcp-common.c:880
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:876
+#: dhcp-common.c:883
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:918
+#: dhcp-common.c:925
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
-#: dhcp-common.c:920
+#: dhcp-common.c:927
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:922
+#: dhcp-common.c:929
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
-#: dhcp-common.c:923
+#: dhcp-common.c:930
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:936
+#: dhcp-common.c:943
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:939
+#: dhcp-common.c:946
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr ""
 
-#: dhcp-common.c:950
+#: dhcp-common.c:957
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:952
+#: dhcp-common.c:959
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2221,31 +2329,119 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr ""
 
-#: auth.c:439
+#: auth.c:464
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
 
-#: ipset.c:95
+#: ipset.c:99
 #, c-format
-msgid "failed to find kernel version: %s"
+msgid "failed to create IPset control socket: %s"
 msgstr ""
 
-#: ipset.c:114
+#: ipset.c:211
 #, c-format
-msgid "failed to create IPset control socket: %s"
+msgid "failed to update ipset %s: %s"
 msgstr ""
 
-#: ipset.c:226
+#: pattern.c:29
 #, c-format
-msgid "failed to update ipset %s: %s"
+msgid "[pattern.c:%d] Assertion failure: %s"
+msgstr ""
+
+#: pattern.c:142
+#, c-format
+msgid "Invalid DNS name: Invalid character %c."
+msgstr ""
+
+#: pattern.c:151
+msgid "Invalid DNS name: Empty label."
+msgstr ""
+
+#: pattern.c:156
+msgid "Invalid DNS name: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:170
+msgid "Invalid DNS name: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:176
+#, c-format
+msgid "Invalid DNS name: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:184
+#, c-format
+msgid "Invalid DNS name: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:189
+msgid "Invalid DNS name: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:199
+msgid "Invalid DNS name: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:204
+#, c-format
+msgid "DNS name has invalid length (%zu)."
+msgstr ""
+
+#: pattern.c:258
+#, c-format
+msgid "Invalid DNS name pattern: Invalid character %c."
+msgstr ""
+
+#: pattern.c:267
+msgid "Invalid DNS name pattern: Empty label."
+msgstr ""
+
+#: pattern.c:272
+msgid "Invalid DNS name pattern: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:285
+msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+msgstr ""
+
+#: pattern.c:295
+msgid "Invalid DNS name pattern: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:301
+#, c-format
+msgid "Invalid DNS name pattern: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:309
+#, c-format
+msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:314
+msgid "Invalid DNS name pattern: Wildcard within final two labels."
+msgstr ""
+
+#: pattern.c:319
+msgid "Invalid DNS name pattern: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:329
+msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:334
+#, c-format
+msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
 msgstr ""
 
 #: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: dnssec.c:902
+#: dnssec.c:1014
 #, c-format
 msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
 msgstr ""
@@ -2277,7 +2473,7 @@ msgstr ""
 
 #: tables.c:101
 #, c-format
-msgid "IPset: error:%s"
+msgid "IPset: error: %s"
 msgstr ""
 
 #: tables.c:108
@@ -2339,51 +2535,42 @@ msgstr ""
 msgid "bad header in %s"
 msgstr ""
 
-#: dump.c:201
+#: dump.c:205
 msgid "failed to write packet dump"
 msgstr ""
 
-#: dump.c:203
+#: dump.c:207
 #, c-format
 msgid "dumping UDP packet %u mask 0x%04x"
 msgstr ""
 
-#: ubus.c:52
+#: ubus.c:79
 #, c-format
 msgid "UBus subscription callback: %s subscriber(s)"
 msgstr ""
 
-#: ubus.c:73
+#: ubus.c:99
 #, c-format
 msgid "Cannot reconnect to UBus: %s"
 msgstr ""
 
-#: ubus.c:89
-msgid "Cannot initialize UBus: connection failed"
-msgstr ""
-
-#: ubus.c:102
-#, c-format
-msgid "Cannot add object to UBus: %s"
-msgstr ""
-
-#: ubus.c:112
-msgid "Connected to system UBus"
-msgstr ""
-
-#: ubus.c:122
+#: ubus.c:135
 msgid "Cannot set UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:142
+#: ubus.c:155
 msgid "Cannot poll UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:155
+#: ubus.c:168
 msgid "Disconnecting from UBus"
 msgstr ""
 
-#: ubus.c:199
+#: ubus.c:179 ubus.c:326
 #, c-format
-msgid "Failed to send UBus event: %s"
+msgid "UBus command failed: %d (%s)"
+msgstr ""
+
+#: hash-questions.c:40
+msgid "Failed to create SHA-256 hash object"
 msgstr ""
index 630885d..a97dc2f 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -14,806 +14,839 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
 
-#: cache.c:559
+#: cache.c:572
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:1081
+#: cache.c:1094
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr "Impossible de charger les noms à partir de %s : %s"
 
-#: cache.c:1103 dhcp.c:927
+#: cache.c:1116 dhcp.c:931
 #, c-format
 msgid "bad address at %s line %d"
 msgstr "mauvaise adresse dans %s ligne %d"
 
-#: cache.c:1156 dhcp.c:943
+#: cache.c:1169 dhcp.c:947
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "mauvais nom dans %s ligne %d"
 
-#: cache.c:1167 dhcp.c:1018
+#: cache.c:1180 dhcp.c:1022
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "lecture %s - %d adresses"
 
-#: cache.c:1283
+#: cache.c:1296
 msgid "cleared cache"
 msgstr "cache vidé"
 
-#: cache.c:1345
+#: cache.c:1358
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr "Aucune adresse IPv4 trouvée pour %s"
 
-#: cache.c:1391
+#: cache.c:1404
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr "%s est un CNAME, il ne sera pas donné au bail DHCP de %s"
 
-#: cache.c:1415
+#: cache.c:1428
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "ne donne pas de nom %s au bail DHCP de %s parce-que le nom existe dans %s avec l'adresse %s"
 
-#: cache.c:1663
+#: cache.c:1674
 #, c-format
 msgid "time %lu"
 msgstr "horodatage %lu"
 
-#: cache.c:1664
+#: cache.c:1675
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "taille de cache %d, %d/%d insertions dans le cache entrées non-expirées réutilisées"
 
-#: cache.c:1666
+#: cache.c:1677
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr "requêtes transmises %u, requêtes résolues localement %u"
 
-#: cache.c:1669
+#: cache.c:1680
 #, fuzzy, c-format
 msgid "queries for authoritative zones %u"
 msgstr "Configure la durée de vie (Time To Live) pour les réponses faisant autorité"
 
-#: cache.c:1694
+#: cache.c:1702
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr "serveur %s#%d: requêtes envoyées %u, requêtes réessayées ou échouées %u"
 
-#: util.c:47
+#: util.c:51
 #, c-format
 msgid "failed to seed the random number generator: %s"
 msgstr "impossible d'initialiser le générateur de nombre aléatoire : %s"
 
-#: util.c:224
+#: util.c:228
 msgid "failed to allocate memory"
 msgstr "impossible d'allouer la mémoire"
 
-#: util.c:281 option.c:641
+#: util.c:285 option.c:665
 msgid "could not get memory"
 msgstr "impossible d'allouer de la mémoire"
 
-#: util.c:302
+#: util.c:306
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr "Ne peut pas créer le tube %s : %s"
 
-#: util.c:310
+#: util.c:314
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr "impossible d'allouer %d octets"
 
-#: util.c:506
+#: util.c:520
 #, c-format
 msgid "infinite"
 msgstr "illimité(e)"
 
-#: option.c:358
+#: util.c:808
+#, c-format
+msgid "failed to find kernel version: %s"
+msgstr "impossible de trouver la version de noyau : %s"
+
+#: option.c:372
 msgid "Specify local address(es) to listen on."
 msgstr "Spécifie la ou les adresse(s) locales où le démon doit se mettre à l'écoute."
 
-#: option.c:359
+#: option.c:373
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Retourne les adresses IP pour toutes les machines présentes dans les domaines spécifiés"
 
-#: option.c:360
+#: option.c:374
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Traduction inverse truquée pour la plage d'adresse privée RFC1918"
 
-#: option.c:361
+#: option.c:375
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Traite l'adresse IP comme un domaine inexistant NXDOMAIN (contourne le systeme de redirection de Verisign)"
 
-#: option.c:362
+#: option.c:376
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Spécifie le nombre d'entrées que contiendra le cache (par défaut : %s)."
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Spécifie le nom du fichier de configuration (par défaut : %s)"
 
-#: option.c:364
+#: option.c:378
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "Ne passe pas en tâche de fond : démarre en mode debug"
 
-#: option.c:365
+#: option.c:379
 msgid "Do NOT forward queries with no domain part."
 msgstr "Ne retransmet pas les requêtes qui n'ont pas de domaine."
 
-#: option.c:366
+#: option.c:380
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Retourne les champs MX pour les machines locales."
 
-#: option.c:367
+#: option.c:381
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Etend les noms uniques des machines dans /etc/hosts avec le suffixe du domaine."
 
-#: option.c:368
+#: option.c:382
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "Ne retransmet pas les fausses requêtes DNS en provenance des machines Windows."
 
-#: option.c:369
+#: option.c:383
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Autorise DHCP dans la plage d'adresses donnée sur la durée de validité du bail."
 
-#: option.c:370
+#: option.c:384
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "On change pour ce groupe après le démarrage (par défaut : %s)."
 
-#: option.c:371
+#: option.c:385
 msgid "Set address or hostname for a specified machine."
 msgstr "On assigne une adresse ou un nom pour une machine spécifiée."
 
-#: option.c:372
+#: option.c:386
 msgid "Read DHCP host specs from file."
 msgstr "Lecture des spécifications d'hôtes DHCP à partir du fichier"
 
-#: option.c:373
+#: option.c:387
 msgid "Read DHCP option specs from file."
 msgstr "Lecture des options DHCP à partir du fichier"
 
-#: option.c:374
+#: option.c:388
 #, fuzzy
 msgid "Read DHCP host specs from a directory."
 msgstr "Lecture des spécifications d'hôtes DHCP à partir du fichier"
 
-#: option.c:375
+#: option.c:389
 #, fuzzy
 msgid "Read DHCP options from a directory."
 msgstr "Lecture des options DHCP à partir du fichier"
 
-#: option.c:376
+#: option.c:390
 msgid "Evaluate conditional tag expression."
 msgstr "Expression d'évaluation conditionnelle d'étiquette"
 
-#: option.c:377
+#: option.c:391
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "Ne charge PAS le fichier %s."
 
-#: option.c:378
+#: option.c:392
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Spécifie un nom de fichier hosts à lire en complément de %s"
 
-#: option.c:379
+#: option.c:393
 #, fuzzy
 msgid "Read hosts files from a directory."
 msgstr "Lecture des spécifications d'hôtes DHCP à partir du fichier"
 
-#: option.c:380
+#: option.c:394
 msgid "Specify interface(s) to listen on."
 msgstr "Spécifie la ou les interface(s) où le démon doit se mettre à l'écoute."
 
-#: option.c:381
+#: option.c:395
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Spécifie la ou les interface(s) que le démon ne doit PAS traiter."
 
 #
-#: option.c:382
+#: option.c:396
 msgid "Map DHCP user class to tag."
 msgstr "Associe les classes d'utilisateurs ('user class') DHCP aux options."
 
-#: option.c:383
+#: option.c:397
 msgid "Map RFC3046 circuit-id to tag."
 msgstr "Associe les identifiants de circuits RFC3046 ('circuit-id') aux options"
 
-#: option.c:384
+#: option.c:398
 msgid "Map RFC3046 remote-id to tag."
 msgstr "Associe les identifiants distants RFC3046 ('remote-id') aux options"
 
-#: option.c:385
+#: option.c:399
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr "Associe les identifiants de souscripteurs RFC3993 ('subscriber-id') aux options"
 
+#: option.c:400
+msgid "Specify vendor class to match for PXE requests."
+msgstr ""
+
 #
-#: option.c:386
+#: option.c:401
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Ne pas autoriser DHCP pour les machines énumerées dans les options."
 
 #
-#: option.c:387
+#: option.c:402
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Forcer les réponses par 'broadcast' pour les machines énumerées dans les options."
 
-#: option.c:388
+#: option.c:403
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "Ne passe pas en tâche de fond, ne pas s'exécuter en mode debug."
 
-#: option.c:389
+#: option.c:404
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "On considère que l'on est le seul serveur DHCP sur le réseau local."
 
-#: option.c:390
+#: option.c:405
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Spécifie où il faut sauvegarder les baux DHCP (par défaut : %s)."
 
-#: option.c:391
+#: option.c:406
 msgid "Return MX records for local hosts."
 msgstr "Retourne les champs MX pour les machines locales."
 
-#: option.c:392
+#: option.c:407
 msgid "Specify an MX record."
 msgstr "Spécifie un champ MX."
 
-#: option.c:393
+#: option.c:408
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Spécifie les options BOOTP pour le serveur DHCP."
 
-#: option.c:394
+#: option.c:409
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "Ne pas scruter le fichier %s, ne recharger les modifications que sur réception du signal SIGHUP."
 
-#: option.c:395
+#: option.c:410
 msgid "Do NOT cache failed search results."
 msgstr "Ne place pas en cache le résultat des requêtes qui ont échouées."
 
-#: option.c:396
+#: option.c:411
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Utilise les serveurs de noms dans l'ordre donné dans %s."
 
 #
-#: option.c:397
+#: option.c:412
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Options supplémentaires à associer aux clients DHCP."
 
-#: option.c:398
+#: option.c:413
 msgid "DHCP option sent even if the client does not request it."
 msgstr "Option DHCP envoyée même si le client de la demande pas."
 
-#: option.c:399
+#: option.c:414
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Spécifie le port où il faut écouter les requêtes DNS (par défaut : 53)."
 
-#: option.c:400
+#: option.c:415
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Taille maximale des paquets UDP supportés pour EDNS.0 (par défaut : %s)."
 
 #
-#: option.c:401
+#: option.c:416
 msgid "Log DNS queries."
 msgstr "Enregistre les requêtes DNS dans un journal d'activité."
 
 #
-#: option.c:402
+#: option.c:417
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Force le port d'origine pour les requêtes vers les serveurs amonts."
 
-#: option.c:403
+#: option.c:418
 msgid "Do NOT read resolv.conf."
 msgstr "Ne pas lire le fichier resolv.conf."
 
-#: option.c:404
+#: option.c:419
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Spécifie le chemin pour le fichier resolv.conf (par défaut : %s)."
 
-#: option.c:405
+#: option.c:420
 #, fuzzy
 msgid "Specify path to file with server= options"
 msgstr "Spécifie un chemin pour le fichier PID (par défaut : %s)."
 
-#: option.c:406
+#: option.c:421
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Spécifie la ou les adresses des serveurs amonts avec des domaines optionels."
 
-#: option.c:407
+#: option.c:422
 #, fuzzy
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Spécifie la ou les adresses des serveurs amonts avec des domaines optionels."
 
-#: option.c:408
+#: option.c:423
 msgid "Never forward queries to specified domains."
 msgstr "Ne jamais retransmettre les requêtes pour les domaines spécifiés."
 
-#: option.c:409
+#: option.c:424
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Spécifie le domaine qui doit etre assigné aux baux DHCP."
 
-#: option.c:410
+#: option.c:425
 msgid "Specify default target in an MX record."
 msgstr "Spécifie la cible par défaut dans un champ MX."
 
-#: option.c:411
+#: option.c:426
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Spécifie le TTL en secondes pour les réponses qui utilisent /etc/hosts."
 
 #
-#: option.c:412
+#: option.c:427
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Spécifie le TTL en secondes pour les réponses qui utilisent /etc/hosts."
 
-#: option.c:413
+#: option.c:428
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Spécifie, en secondes, la valeur maximum de TTL à renvoyer aux clients."
 
 #
-#: option.c:414
+#: option.c:429
 #, fuzzy
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Spécifie le TTL en secondes pour les réponses qui utilisent /etc/hosts."
 
 #
-#: option.c:415
+#: option.c:430
 #, fuzzy
 msgid "Specify time-to-live floor for cache."
 msgstr "Spécifie le TTL en secondes pour les réponses qui utilisent /etc/hosts."
 
-#: option.c:416
+#: option.c:431
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Change pour cet utilisateur après le démarrage (par défaut : %s)."
 
 #
-#: option.c:417
+#: option.c:432
 msgid "Map DHCP vendor class to tag."
 msgstr "Associe les classes de fournisseurs ('vendor class') DHCP aux options."
 
-#: option.c:418
+#: option.c:433
 msgid "Display dnsmasq version and copyright information."
 msgstr "Affiche la version de Dnsmasq et les informations liées au copyright."
 
-#: option.c:419
+#: option.c:434
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Traduit les adresses IPV4 des serveurs amonts."
 
-#: option.c:420
+#: option.c:435
 msgid "Specify a SRV record."
 msgstr "Spécifie un champ SRV."
 
-#: option.c:421
+#: option.c:436
 #, fuzzy
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr "Afficher ce message. Utiliser --help dhcp pour obtenir la liste des options DHCP connues."
 
-#: option.c:422
+#: option.c:437
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Spécifie un chemin pour le fichier PID (par défaut : %s)."
 
-#: option.c:423
+#: option.c:438
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Spécifie le nombre maximum de baux DHCP (par défaut : %s)."
 
-#: option.c:424
+#: option.c:439
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Repond aux requêtes DNS en se basant sur l'interface ou a été envoyée la requête."
 
-#: option.c:425
+#: option.c:440
 msgid "Specify TXT DNS record."
 msgstr "Spécifie un champ DNS TXT"
 
 #
-#: option.c:426
+#: option.c:441
 msgid "Specify PTR DNS record."
 msgstr "Spécifie un champ DNS PTR"
 
-#: option.c:427
+#: option.c:442
 msgid "Give DNS name to IPv4 address of interface."
 msgstr "Donne le nom DNS pour l'adresse IPv4 de l'interface."
 
-#: option.c:428
+#: option.c:443
 msgid "Bind only to interfaces in use."
 msgstr "Association uniquement aux interfaces réseau actuellement actives."
 
-#: option.c:429
+#: option.c:444
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Lecture des informations de DHCP statique à partir de %s."
 
-#: option.c:430
+#: option.c:445
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Autorise l'interface DBus pour la configuration des serveurs amonts, etc."
 
-#: option.c:431
+#: option.c:446
 msgid "Enable the UBus interface."
 msgstr ""
 
-#: option.c:432
+#: option.c:447
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "Ne pas assurer de fonction DHCP sur cette interface, mais seulement la fonction DNS."
 
-#: option.c:433
+#: option.c:448
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Autorise l'allocation dynamique d'adresse pour bootp."
 
 #
-#: option.c:434
+#: option.c:449
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Associe l'adresse MAC (avec les jokers) aux options."
 
-#: option.c:435
+#: option.c:450
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr "Traiter les requêtes DHCP sur les alias comme arrivant de l'interface."
 
-#: option.c:436
+#: option.c:451
 msgid "Specify extra networks sharing a broadcast domain for DHCP"
 msgstr ""
 
-#: option.c:437
+#: option.c:452
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr "Supprime la vérification d'adresse sur le serveur au moyen de paquets ICMP echo"
 
-#: option.c:438
+#: option.c:453
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr "Script shell à exécuter lors de la création ou destruction de bail DHCP."
 
-#: option.c:439
+#: option.c:454
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr "Script Lua à exécuter lors de la création ou destruction de bail DHCP."
 
-#: option.c:440
+#: option.c:455
 msgid "Run lease-change scripts as this user."
 msgstr "Lancer le script 'lease-change' avec cet utilisateur."
 
-#: option.c:441
+#: option.c:456
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:442
+#: option.c:457
 msgid "Read configuration from all the files in this directory."
 msgstr "Lecture de la configuration dans tous les fichiers de ce répertoire."
 
 #
-#: option.c:443
+#: option.c:458
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Enregistrer les journaux d'activité dans cette facilité syslog. (défaut : DAEMON)"
 
-#: option.c:444
+#: option.c:459
 msgid "Do not use leasefile."
 msgstr "Ne pas utiliser de fichier de baux."
 
-#: option.c:445
+#: option.c:460
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Spécifie le nombre maximum de requêtes DHCP concurrentes (par défaut : %s)."
 
-#: option.c:446
+#: option.c:461
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr "Vider le cache DNS lors du rechargement de %s."
 
-#: option.c:447
+#: option.c:462
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr "Ignorer les noms d'hôtes fournis par les clients DHCP"
 
-#: option.c:448
+#: option.c:463
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr "Ne pas réutiliser les champs nom de fichier et serveur dans les options DHCP supplémentaires."
 
-#: option.c:449
+#: option.c:464
 msgid "Enable integrated read-only TFTP server."
 msgstr "Activer le server TFTP intégré (fonctionnant en lecture seulement)"
 
-#: option.c:450
+#: option.c:465
 msgid "Export files by TFTP only from the specified subtree."
 msgstr "N'exporter par TFTP que les fichiers de l'arborescence de fichier spécifiée"
 
-#: option.c:451
+#: option.c:466
 #, fuzzy
 msgid "Add client IP or hardware address to tftp-root."
 msgstr "Ajouter les adresses IP clientes à la racine tftp ('tftp-root')."
 
-#: option.c:452
+#: option.c:467
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr "Accès aux seuls fichiers appartenants à l'utilisateur sous lequel tourne dnsmasq"
 
-#: option.c:453
+#: option.c:468
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:454
+#: option.c:469
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Spécifie le nombre maximum de transfert TFTP concurrents (défaut : %s)."
 
-#: option.c:455
+#: option.c:470
 #, fuzzy
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Spécifie le nombre maximum de transfert TFTP concurrents (défaut : %s)."
 
-#: option.c:456
+#: option.c:471
 msgid "Disable the TFTP blocksize extension."
 msgstr "Désactivation de l'extension TFTP « taille de bloc »"
 
-#: option.c:457
+#: option.c:472
 msgid "Convert TFTP filenames to lowercase"
 msgstr "Convertis les noms de fichiers TFTP en minuscule"
 
-#: option.c:458
+#: option.c:473
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr "Gamme de ports dans laquelle seront choisis les ports temporaires utilisés dans les transferts TFTP."
 
-#: option.c:459
+#: option.c:474
 msgid "Use only one port for TFTP server."
 msgstr ""
 
-#: option.c:460
+#: option.c:475
 msgid "Extra logging for DHCP."
 msgstr "Traces supplémentaires pour le DHCP."
 
-#: option.c:461
+#: option.c:476
 msgid "Enable async. logging; optionally set queue length."
 msgstr "Active l'écriture de traces en mode asynchrone. Peut prendre en option la valeur de la longueur de la queue."
 
-#: option.c:462
+#: option.c:477
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr "Stopper la réassociation DNS ('DNS rebinding'). Filtre les gammes d'adresses IP privées lors de la résolution."
 
-#: option.c:463
+#: option.c:478
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr "Autorise la réassociation de 127.0.0/8, pour les serveurs RBL (Realtime Blackhole List)"
 
-#: option.c:464
+#: option.c:479
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr "Désactive la protection contre les réassociation DNS pour ce domaine"
 
-#: option.c:465
+#: option.c:480
 msgid "Always perform DNS queries to all servers."
 msgstr "Toujours effectuer les requêtes DNS à tous les serveurs."
 
 #
-#: option.c:466
+#: option.c:481
 msgid "Set tag if client includes matching option in request."
 msgstr "Spécifie le label si le client inclus l'option dans la requête."
 
 #
-#: option.c:467
+#: option.c:482
 #, fuzzy
 msgid "Set tag if client provides given name."
 msgstr "Spécifie le label si le client inclus l'option dans la requête."
 
-#: option.c:468
+#: option.c:483
 msgid "Use alternative ports for DHCP."
 msgstr "Utiliser des ports alternatifs pour le DHCP."
 
 #
-#: option.c:469
+#: option.c:484
 msgid "Specify NAPTR DNS record."
 msgstr "Spécifie un champ DNS NAPTR."
 
-#: option.c:470
+#: option.c:485
 msgid "Specify lowest port available for DNS query transmission."
 msgstr "Définie le plus petit port utilisé pour la transmission d'une requête DNS."
 
-#: option.c:471
+#: option.c:486
 #, fuzzy
 msgid "Specify highest port available for DNS query transmission."
 msgstr "Définie le plus petit port utilisé pour la transmission d'une requête DNS."
 
-#: option.c:472
+#: option.c:487
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr "Utilise seulement les noms de domaine pleinement qualifiés pour les clients DHCP."
 
-#: option.c:473
+#: option.c:488
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr "Génère les noms d'hôtes à partir de l'adresse MAC pour les clients sans nom."
 
-#: option.c:474
+#: option.c:489
 msgid "Use these DHCP relays as full proxies."
 msgstr "Utilise ces relais DHCP en temps que proxy complets."
 
-#: option.c:475
+#: option.c:490
 msgid "Relay DHCP requests to a remote server"
 msgstr "Requêtes de relais DHCP à un serveur distant"
 
-#: option.c:476
+#: option.c:491
 msgid "Specify alias name for LOCAL DNS name."
 msgstr "Spécifie un alias pour un nom DNS local."
 
 #
-#: option.c:477
+#: option.c:492
 msgid "Prompt to send to PXE clients."
 msgstr "Invite à envoyer aux clients PXE."
 
-#: option.c:478
+#: option.c:493
 msgid "Boot service for PXE menu."
 msgstr "Service de démarrage pour menu PXE."
 
-#: option.c:479
+#: option.c:494
 msgid "Check configuration syntax."
 msgstr "vérification de la syntaxe de la configuration."
 
-#: option.c:480
+#: option.c:495
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr "Ajoute l'adresse MAC du requêteur aux requêtes DNS transmises"
 
-#: option.c:481
+#: option.c:496
 #, fuzzy
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr "Ajoute l'adresse MAC du requêteur aux requêtes DNS transmises"
 
-#: option.c:482
+#: option.c:497
 #, fuzzy
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Ajoute l'adresse MAC du requêteur aux requêtes DNS transmises"
 
-#: option.c:483
+#: option.c:498
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Copie dans la réponse DNS le résultat de la validation DNSSEC effectuée par les serveurs DNS amonts."
 
-#: option.c:484
+#: option.c:499
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr "Essaie d'allouer des adresses IP séquentielles aux clients DHCP."
 
-#: option.c:485
+#: option.c:500
 #, fuzzy
 msgid "Ignore client identifier option sent by DHCP clients."
 msgstr "Ignorer les noms d'hôtes fournis par les clients DHCP"
 
-#: option.c:486
+#: option.c:501
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr "Copie les marques de suivi de connexion pour les requêtes amont."
 
-#: option.c:487
+#: option.c:502
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr "Autoriser les clients DHCP à faire leurs propres mises à jour DDNS (Dynamic DNS)"
 
-#: option.c:488
+#: option.c:503
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr "Envoyer des annonces de routeurs pour toutes les interfaces faisant du DHCPv6"
 
-#: option.c:489
+#: option.c:504
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr "Spécifie pour le serveur DHCPv6 un identifiant unique DHCP (DUID) basé sur un numéro unique de vendeur (DUID_EN)"
 
-#: option.c:490
+#: option.c:505
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Spécifie les enregistrements (A/AAAA et PTR) d'un hôte."
 
-#: option.c:491
+#: option.c:506
+msgid "Specify host record in interface subnet"
+msgstr ""
+
+#: option.c:507
 msgid "Specify certification authority authorization record"
 msgstr ""
 
-#: option.c:492
+#: option.c:508
 msgid "Specify arbitrary DNS resource record"
 msgstr "Définie une resource DNS d'un type spécifique"
 
-#: option.c:493
+#: option.c:509
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "Se lie aux interfaces préexistantes - vérifie l'apparition de nouvelles interfaces"
 
-#: option.c:494
+#: option.c:510
 msgid "Export local names to global DNS"
 msgstr "Exporte les noms locaux dans le DNS global"
 
-#: option.c:495
+#: option.c:511
 msgid "Domain to export to global DNS"
 msgstr "Domaine à exporter dans le DNS global"
 
-#: option.c:496
+#: option.c:512
 msgid "Set TTL for authoritative replies"
 msgstr "Configure la durée de vie (Time To Live) pour les réponses faisant autorité"
 
-#: option.c:497
+#: option.c:513
 #, fuzzy
 msgid "Set authoritative zone information"
 msgstr "Configure les informations pour une zone de nom faisant autorité"
 
-#: option.c:498
+#: option.c:514
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr "Serveurs de noms secondaires faisant autorité pour les domaines délégués"
 
-#: option.c:499
+#: option.c:515
 msgid "Peers which are allowed to do zone transfer"
 msgstr "Pairs autorisés à faire des transferts de zone"
 
-#: option.c:500
+#: option.c:516
 msgid "Specify ipsets to which matching domains should be added"
 msgstr "Spécifie les ipsets auxquels les domaines correspondants doivent-être ajoutés"
 
-#: option.c:501
+#: option.c:517
+msgid "Enable filtering of DNS queries with connection-track marks."
+msgstr ""
+
+#: option.c:518
+msgid "Set allowed DNS patterns for a connection-track mark."
+msgstr ""
+
+#: option.c:519
 #, fuzzy
 msgid "Specify a domain and address range for synthesised names"
 msgstr "Spécifie un domaine et une plage d'adresses pour les noms auto-générés"
 
-#: option.c:502
+#: option.c:520
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:503
+#: option.c:521
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:504
+#: option.c:522
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:505
+#: option.c:523
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:506
+#: option.c:524
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:507
+#: option.c:525
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:508
+#: option.c:526
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:509
+#: option.c:527
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:510
+#: option.c:528
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:511
+#: option.c:529
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:512
+#: option.c:530
+msgid "Log debugging information."
+msgstr ""
+
+#: option.c:531
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:513
+#: option.c:532
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:514
+#: option.c:533
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:515
+#: option.c:534
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:516
+#: option.c:535
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:517
+#: option.c:536
 msgid "Enables DHCPv4 Rapid Commit option."
 msgstr ""
 
-#: option.c:518
+#: option.c:537
 msgid "Path to debug packet dump file"
 msgstr ""
 
-#: option.c:519
+#: option.c:538
 msgid "Mask which packets to dump"
 msgstr ""
 
-#: option.c:520
+#: option.c:539
 msgid "Call dhcp-script when lease expiry changes."
 msgstr ""
 
-#: option.c:725
+#: option.c:540
+msgid "Send Cisco Umbrella identifiers including remote IP."
+msgstr ""
+
+#: option.c:541
+msgid "Do not log routine TFTP."
+msgstr ""
+
+#: option.c:771
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -822,354 +855,397 @@ msgstr ""
 "Usage : dnsmasq [options]\n"
 "\n"
 
-#: option.c:727
+#: option.c:773
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Utilisez les options courtes uniquement sur la ligne de commande.\n"
 
-#: option.c:729
+#: option.c:775
 #, c-format
 msgid "Valid options are:\n"
 msgstr "Les options valides sont :\n"
 
 #
-#: option.c:776 option.c:884
+#: option.c:822 option.c:933
 msgid "bad address"
 msgstr "mauvaise adresse"
 
-#: option.c:799 option.c:803
+#: option.c:847 option.c:851
 msgid "bad port"
 msgstr "numéro de port incorrect"
 
-#: option.c:815 option.c:844 option.c:878
+#: option.c:864 option.c:893 option.c:927
 msgid "interface binding not supported"
 msgstr "association d'interface non supportée"
 
-#: option.c:839 option.c:873
+#: option.c:888 option.c:922
 msgid "interface can only be specified once"
 msgstr ""
 
 #
-#: option.c:852 option.c:4042
+#: option.c:901 option.c:4362
 msgid "bad interface name"
 msgstr "nom d'interface invalide"
 
-#: option.c:1184
+#: option.c:1192
+msgid "inappropriate vendor:"
+msgstr ""
+
+#: option.c:1199
+msgid "inappropriate encap:"
+msgstr ""
+
+#: option.c:1225
 msgid "unsupported encapsulation for IPv6 option"
 msgstr "encapsulation d'option non supportée pour IPv6"
 
-#: option.c:1198
+#: option.c:1239
 msgid "bad dhcp-option"
 msgstr "mauvaise valeur de 'dhcp-option'"
 
 #
-#: option.c:1270
+#: option.c:1317
 msgid "bad IP address"
 msgstr "mauvaise adresse IP"
 
 #
-#: option.c:1273 option.c:1412 option.c:3297
+#: option.c:1320 option.c:1459 option.c:3551
 msgid "bad IPv6 address"
 msgstr "mauvaise adresse IPv6"
 
 #
-#: option.c:1366
+#: option.c:1413
 #, fuzzy
 msgid "bad IPv4 address"
 msgstr "mauvaise adresse IPv6"
 
-#: option.c:1439 option.c:1533
+#: option.c:1486 option.c:1581
 msgid "bad domain in dhcp-option"
 msgstr "mauvais domaine dans dhcp-option"
 
-#: option.c:1571
+#: option.c:1625
 msgid "dhcp-option too long"
 msgstr "dhcp-option trop long"
 
-#: option.c:1578
+#: option.c:1632
 msgid "illegal dhcp-match"
 msgstr "valeur illégale pour 'dhcp-match'"
 
-#: option.c:1647
+#: option.c:1691
 msgid "illegal repeated flag"
 msgstr "Une option ne pouvant être spécifié qu'une seule fois à été donnée plusieurs fois"
 
-#: option.c:1655
+#: option.c:1699
 msgid "illegal repeated keyword"
 msgstr "Mot-clef ne pouvant être répété"
 
-#: option.c:1726 option.c:4764
+#: option.c:1770 option.c:5080
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr "Ne peut pas lire le répertoire %s : %s"
 
-#: option.c:1772 tftp.c:564 dump.c:68
+#: option.c:1816 tftp.c:566 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr "Ne peut pas lire %s : %s"
 
-#: option.c:1879
+#: option.c:1931
 msgid "setting log facility is not possible under Android"
 msgstr "Sous android, impossible de positionner la cible (facility) pour les traces (logs)."
 
-#: option.c:1888
+#: option.c:1940
 msgid "bad log facility"
 msgstr "Mauvaise cible (facility) pour les traces."
 
-#: option.c:1941
+#: option.c:1993
 msgid "bad MX preference"
 msgstr "préference MX incorrecte"
 
-#: option.c:1946
+#: option.c:1998
 msgid "bad MX name"
 msgstr "nom MX incorrect"
 
-#: option.c:1960
+#: option.c:2012
 msgid "bad MX target"
 msgstr "valeur MX cible incorrecte"
 
-#: option.c:1980
+#: option.c:2032
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr "recompiler en définissant HAVE_SCRIPT pour permettre l'exécution de scripts shell au changement de bail (lease-change)"
 
-#: option.c:1984
+#: option.c:2036
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr "recompiler en définissant HAVE_LUASCRIPT pour permettre l'exécution de scripts LUA au changement de bail (lease-change)"
 
-#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
+#: option.c:2291 option.c:2327
+#, fuzzy
+msgid "bad prefix length"
+msgstr "mauvais préfixe"
+
+#: option.c:2303 option.c:2348 option.c:2398
 msgid "bad prefix"
 msgstr "mauvais préfixe"
 
-#: option.c:2658
+#: option.c:2418
+#, fuzzy
+msgid "prefix length too small"
+msgstr "la taille de préfixe doit être au minimum 64"
+
+#: option.c:2697
+#, fuzzy
+msgid "Bad address in --address"
+msgstr "adresse déjà utilisée"
+
+#: option.c:2751
+#, fuzzy
+msgid "bad IPv4 prefix"
+msgstr "mauvais préfixe"
+
+#: option.c:2756 option.c:3569
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "mauvais préfixe"
+
+#: option.c:2777
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr "recompiler en définissant HAVE_IPSET pour permettre l'utilisation de directives de groupes d'IP (IPset)"
 
+#: option.c:2843 option.c:2861
+#, fuzzy
+msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+msgstr "recompiler en définissant HAVE_IPSET pour permettre l'utilisation de directives de groupes d'IP (IPset)"
+
 #
-#: option.c:2871
+#: option.c:3119
 msgid "bad port range"
 msgstr "gamme de ports incorrecte"
 
-#: option.c:2897
+#: option.c:3145
 msgid "bad bridge-interface"
 msgstr "interface-pont incorrecte"
 
-#: option.c:2941
+#: option.c:3189
 msgid "bad shared-network"
 msgstr ""
 
-#: option.c:2996
+#: option.c:3243
 msgid "only one tag allowed"
 msgstr "une seule étiquette est autorisée"
 
-#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
+#: option.c:3264 option.c:3280 option.c:3406 option.c:3414 option.c:3457
 msgid "bad dhcp-range"
 msgstr "plage d'adresses DHCP (dhcp-range) incorrecte"
 
-#: option.c:3050
+#: option.c:3298
 msgid "inconsistent DHCP range"
 msgstr "plage d'adresses DHCP incohérente"
 
-#: option.c:3115
+#: option.c:3364
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr "la taille du préfixe doit être exactement 64 pour les sous-réseaux d'annonces de routeurs (RA)"
 
-#: option.c:3117
+#: option.c:3366
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr "la taille du préfixe doit être exactement 64 pour le constructeur de sous-réseaux"
 
-#: option.c:3120
+#: option.c:3369
 msgid "prefix length must be at least 64"
 msgstr "la taille de préfixe doit être au minimum 64"
 
-#: option.c:3123
+#: option.c:3372
 msgid "inconsistent DHCPv6 range"
 msgstr "plage d'adresses DHCPv6 incohérente"
 
-#: option.c:3142
+#: option.c:3391
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr "le préfixe doit avoir une taille de 0 lorsque l'argument \"constructor:\" est utilisé"
 
-#: option.c:3262 option.c:3340
+#: option.c:3516 option.c:3594
 msgid "bad hex constant"
 msgstr "mauvaise constante hexadecimale"
 
-#: option.c:3315
-#, fuzzy
-msgid "bad IPv6 prefix"
-msgstr "mauvais préfixe"
-
-#: option.c:3362
+#: option.c:3617
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "adresse IP dhcp-host dupliquée dans %s."
 
 #
-#: option.c:3422
+#: option.c:3678
 msgid "bad DHCP host name"
 msgstr "nom d'hôte DHCP incorrect"
 
-#: option.c:3508
+#: option.c:3764
 msgid "bad tag-if"
 msgstr "mauvaise étiquette tag-if"
 
-#: option.c:3851 option.c:4324
+#: option.c:4107 option.c:4623
 msgid "invalid port number"
 msgstr "numéro de port invalide"
 
 #
-#: option.c:3907
+#: option.c:4163
 msgid "bad dhcp-proxy address"
 msgstr "adresse dhcp-proxy incorrecte"
 
-#: option.c:3935
+#: option.c:4204
 msgid "Bad dhcp-relay"
 msgstr "valeur incorrecte pour le relais DHCP (dhcp-relay)"
 
-#: option.c:3979
+#: option.c:4248
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3989
+#: option.c:4258
 msgid "bad DUID"
 msgstr "mauvais identifiant unique DHCP (DUID)"
 
-#: option.c:4023
+#: option.c:4292
 #, fuzzy
 msgid "missing address in alias"
 msgstr "adresse non valide"
 
 #
-#: option.c:4029
+#: option.c:4298
 msgid "invalid alias range"
 msgstr "poids invalide"
 
-#: option.c:4081 option.c:4097
+#: option.c:4347
+#, fuzzy
+msgid "missing address in dynamic host"
+msgstr "adresse non valide"
+
+#: option.c:4362
+#, fuzzy
+msgid "bad dynamic host"
+msgstr "Ne peut pas lire le répertoire %s : %s"
+
+#: option.c:4380 option.c:4396
 msgid "bad CNAME"
 msgstr "mauvais CNAME"
 
-#: option.c:4105
+#: option.c:4404
 msgid "duplicate CNAME"
 msgstr "ce CNAME existe déja"
 
 #
-#: option.c:4132
+#: option.c:4431
 msgid "bad PTR record"
 msgstr "mauvais champ PTR"
 
 #
-#: option.c:4167
+#: option.c:4466
 msgid "bad NAPTR record"
 msgstr "mauvais champ NAPTR"
 
 #
-#: option.c:4203
+#: option.c:4502
 msgid "bad RR record"
 msgstr "mauvais enregistrement RR"
 
 #
-#: option.c:4236
+#: option.c:4535
 #, fuzzy
 msgid "bad CAA record"
 msgstr "mauvais enregistrement RR"
 
-#: option.c:4265
+#: option.c:4564
 msgid "bad TXT record"
 msgstr "champ TXT invalide"
 
-#: option.c:4308
+#: option.c:4607
 msgid "bad SRV record"
 msgstr "champ SRV invalide"
 
-#: option.c:4315
+#: option.c:4614
 msgid "bad SRV target"
 msgstr "cible SRV invalide"
 
-#: option.c:4334
+#: option.c:4633
 msgid "invalid priority"
 msgstr "priorité invalide"
 
-#: option.c:4339
+#: option.c:4638
 msgid "invalid weight"
 msgstr "poids invalide"
 
 #
-#: option.c:4362
+#: option.c:4661
 msgid "Bad host-record"
 msgstr "mauvais champ host-record"
 
-#: option.c:4402
+#: option.c:4700
 msgid "Bad name in host-record"
 msgstr "mauvais nom dans le champ host-record"
 
-#: option.c:4444
+#: option.c:4742
 msgid "bad value for dnssec-check-unsigned"
 msgstr ""
 
 #
-#: option.c:4480
+#: option.c:4778
 #, fuzzy
 msgid "bad trust anchor"
 msgstr "gamme de ports incorrecte"
 
-#: option.c:4496
+#: option.c:4794
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4507
+#: option.c:4805
 #, fuzzy
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr "option non supportée (vérifier que Dnsmasq a été compilé avec le support DHCP/TFTP/DBus)"
 
-#: option.c:4567
+#: option.c:4865
 msgid "missing \""
 msgstr "il manque \""
 
-#: option.c:4624
+#: option.c:4922
 msgid "bad option"
 msgstr "mauvaise option"
 
-#: option.c:4626
+#: option.c:4924
 msgid "extraneous parameter"
 msgstr "paramètre en trop"
 
-#: option.c:4628
+#: option.c:4926
 msgid "missing parameter"
 msgstr "paramètre manquant"
 
-#: option.c:4630
+#: option.c:4928
 #, fuzzy
 msgid "illegal option"
 msgstr "mauvaise option"
 
-#: option.c:4637
+#: option.c:4935
 msgid "error"
 msgstr "erreur"
 
-#: option.c:4639
+#: option.c:4937
 #, c-format
 msgid " at line %d of %s"
 msgstr "à la ligne %d de %s"
 
-#: option.c:4654 option.c:4939 option.c:4950
+#: option.c:4952 option.c:5229 option.c:5240
 #, c-format
 msgid "read %s"
 msgstr "Lecture de %s"
 
-#: option.c:4717 option.c:4840 tftp.c:754
+#: option.c:5015 option.c:5162 tftp.c:775
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "Ne peut pas lire %s : %s"
 
-#: option.c:5027
+#: option.c:5316
 msgid "junk found in command line"
 msgstr "la ligne de commande contient des éléments indésirables ou incompréhensibles"
 
-#: option.c:5067
+#: option.c:5356
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Version de Dnsmasq %s  %s\n"
 
-#: option.c:5068
+#: option.c:5357
 #, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1178,562 +1254,597 @@ msgstr ""
 "Options à la compilation %s\n"
 "\n"
 
-#: option.c:5069
+#: option.c:5358
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Ce logiciel est fourni sans AUCUNE GARANTIE.\n"
 
-#: option.c:5070
+#: option.c:5359
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsmasq est un logiciel libre, il vous est permis de le redistribuer\n"
 
-#: option.c:5071
+#: option.c:5360
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "sous les termes de la licence GPL (GNU General Public License), version 2 ou 3.\n"
 
-#: option.c:5088
+#: option.c:5377
 msgid "try --help"
 msgstr "essayez avec --help"
 
-#: option.c:5090
+#: option.c:5379
 msgid "try -w"
 msgstr "essayez avec -w"
 
-#: option.c:5092
+#: option.c:5381
 #, c-format
 msgid "bad command line options: %s"
 msgstr "mauvaises options en ligne de commande : %s."
 
-#: option.c:5161
+#: option.c:5450
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:5195
+#: option.c:5491
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "ne peut pas obtenir le nom de la machine : %s"
 
-#: option.c:5223
+#: option.c:5519
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "seul un fichier resolv.conf est autorisé dans le mode no-poll"
 
-#: option.c:5233
+#: option.c:5529
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "un fichier resolv.conf (et un seul) est nécessaire pour y récuperer le nom de domaine."
 
-#: option.c:5236 network.c:1594 dhcp.c:876
+#: option.c:5532 network.c:1670 dhcp.c:880
 #, c-format
 msgid "failed to read %s: %s"
 msgstr "impossible de lire %s : %s"
 
-#: option.c:5253
+#: option.c:5549
 #, c-format
 msgid "no search directive found in %s"
 msgstr "pas de directive de recherche trouvée dans %s"
 
-#: option.c:5274
+#: option.c:5570
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr "un domaine par défaut doit être spécifié lorsque l'option --dhcp-fqdn est utilisée"
 
-#: option.c:5283
+#: option.c:5579
 msgid "syntax check OK"
 msgstr "vérification de syntaxe OK"
 
-#: forward.c:99
+#: forward.c:104
 #, c-format
 msgid "failed to send packet: %s"
 msgstr "impossible d'envoyer le paquet : %s"
 
-#: forward.c:614
+#: forward.c:601
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:677
+#: forward.c:666
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "le serveur de nom %s a refusé de faire une recherche récursive"
 
-#: forward.c:709
+#: forward.c:702
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr "détection d'une possible attaque de type DNS-rebind: %s"
 
-#: forward.c:961
+#: forward.c:1074
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1370 forward.c:1830
+#: forward.c:1381 forward.c:1910
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2321
+#: forward.c:2198
+#, fuzzy, c-format
+msgid "failed to bind server socket to %s: %s"
+msgstr "impossible de lier la socket de serveur pour %s : %s"
+
+#: forward.c:2494
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Nombre maximum de requêtes DNS concurrentes atteint (maximum : %d)."
 
-#: network.c:698
+#: forward.c:2496
+#, fuzzy, c-format
+msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+msgstr "Nombre maximum de requêtes DNS concurrentes atteint (maximum : %d)."
+
+#: network.c:670
+#, c-format
+msgid "stopped listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:867
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "impossible de créer une socket d'écoute pour %s : %s"
 
-#: network.c:1002
+#: network.c:1148
+#, c-format
+msgid "listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:1175
+#, fuzzy, c-format
+msgid "listening on %s port %d"
+msgstr "impossible d'envoyer %s à %s"
+
+#: network.c:1208
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1009
+#: network.c:1215
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1018
+#: network.c:1224
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "attention : l'interface %s n'existe pas actuellement"
 
-#: network.c:1027
+#: network.c:1233
 #, fuzzy, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "utilise les adresses locales seulement pour %s %s"
 
-#: network.c:1085
+#: network.c:1291
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "impossible de faire rejoindre l'interface %s dans le groupe multicast DHCPv6 %s"
 
-#: network.c:1090
+#: network.c:1296
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1307
+#: network.c:1492
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "impossible de lier la socket de serveur pour %s : %s"
 
-#: network.c:1499
+#: network.c:1569
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignore le serveur de nom %s - interface locale"
 
-#: network.c:1510
+#: network.c:1580
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignore le serveur de nom %s - ne peut construire/lier la socket : %m"
 
-#: network.c:1530
+#: network.c:1598
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1533
+#: network.c:1601
 msgid "unqualified"
 msgstr "non-qualifié(e)"
 
-#: network.c:1533
+#: network.c:1601
 msgid "names"
 msgstr "noms"
 
-#: network.c:1535
+#: network.c:1603
 msgid "default"
 msgstr "défaut"
 
-#: network.c:1537
+#: network.c:1605
 msgid "domain"
 msgstr "domaine"
 
-#: network.c:1543
+#: network.c:1607
 #, fuzzy, c-format
-msgid "using only locally-known addresses for %s %s"
-msgstr "utilise les adresses locales seulement pour %s %s"
-
-#: network.c:1546
-#, c-format
-msgid "using standard nameservers for %s %s"
-msgstr "utilisation des serveurs de nom standards pour %s %s"
-
-#: network.c:1548
-#, fuzzy, c-format
-msgid "using nameserver %s#%d for %s %s %s"
+msgid "using nameserver %s#%d for %s %s%s %s"
 msgstr "utilise le serveur de nom %s#%d pour %s %s"
 
-#: network.c:1552
+#: network.c:1611
 #, fuzzy, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "utilise le serveur de nom %s#%d pour %s %s"
 
-#: network.c:1555
+#: network.c:1614
 #, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "utilise le serveur de nom %s#%d (via %s)"
 
-#: network.c:1557
+#: network.c:1616
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "utilise le serveur de nom %s#%d"
 
-#: network.c:1562
+#: network.c:1630
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s"
+msgstr "utilise les adresses locales seulement pour %s %s"
+
+#: network.c:1633
+#, fuzzy, c-format
+msgid "using standard nameservers for %s"
+msgstr "utilisation des serveurs de nom standards pour %s %s"
+
+#: network.c:1637
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "utilise le serveur de nom %s#%d"
 
-#: network.c:1564
+#: network.c:1639
 #, fuzzy, c-format
 msgid "using %d more nameservers"
 msgstr "utilise le serveur de nom %s#%d"
 
-#: dnsmasq.c:173
+#: dnsmasq.c:184
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:188
+#: dnsmasq.c:199
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:202
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:193
+#: dnsmasq.c:204
 #, fuzzy
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
 
 #
-#: dnsmasq.c:199
+#: dnsmasq.c:210
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "TFTP n'est pas disponible : activez HAVE_TFTP dans src/config.h"
 
-#: dnsmasq.c:204
+#: dnsmasq.c:217
 #, fuzzy
 msgid "cannot use --conntrack AND --query-port"
 msgstr "impossible d'utiliser conjointement --conntrack et --query-port"
 
 #
-#: dnsmasq.c:207
+#: dnsmasq.c:223
 #, fuzzy
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "Support de suivi de connexion non disponible : activez HAVE_CONNTRACK dans src/config.h"
 
-#: dnsmasq.c:212
+#: dnsmasq.c:228
 msgid "asynchronous logging is not available under Solaris"
 msgstr "l'écriture de traces en mode asynchrone n'est pas disponible sous Solaris."
 
-#: dnsmasq.c:217
+#: dnsmasq.c:233
 msgid "asynchronous logging is not available under Android"
 msgstr "l'écriture de traces en mode asynchrone n'est pas disponible sous Android."
 
-#: dnsmasq.c:222
+#: dnsmasq.c:238
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "le mode « autorité DNS » n'est pas disponible : activez HAVE_AUTH dans src/config.h"
 
 #
-#: dnsmasq.c:227
+#: dnsmasq.c:243
 #, fuzzy
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "TFTP n'est pas disponible : activez HAVE_TFTP dans src/config.h"
 
-#: dnsmasq.c:232
+#: dnsmasq.c:248
 #, fuzzy
 msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
 
-#: dnsmasq.c:236
+#: dnsmasq.c:259
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:243
+#: dnsmasq.c:266
 msgid "--auth-server required when an auth zone is defined."
 msgstr ""
 
-#: dnsmasq.c:248
+#: dnsmasq.c:271
 msgid "zone serial must be configured in --auth-soa"
 msgstr "le numéro de série de la zone doit être configuré dans --auth-soa"
 
-#: dnsmasq.c:268
+#: dnsmasq.c:291
 msgid "dhcp-range constructor not available on this platform"
 msgstr "le constructeur de plage dhcp n'est pas disponible sur cette plate-forme"
 
-#: dnsmasq.c:332
+#: dnsmasq.c:355
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr "--bind-interfaces et --bind-dynamic sont mutuellement exclusives"
 
-#: dnsmasq.c:335
+#: dnsmasq.c:358
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "impossible de trouver la liste des interfaces : %s"
 
-#: dnsmasq.c:344
+#: dnsmasq.c:367
 #, c-format
 msgid "unknown interface %s"
 msgstr "interface %s inconnue"
 
-#: dnsmasq.c:406
+#: dnsmasq.c:437
 #, fuzzy
 msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
 msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
 
-#: dnsmasq.c:416 dnsmasq.c:1171
+#: dnsmasq.c:445 dnsmasq.c:1207
 #, c-format
 msgid "DBus error: %s"
 msgstr "Erreur DBus : %s"
 
-#: dnsmasq.c:419
+#: dnsmasq.c:448
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
 
-#: dnsmasq.c:429
+#: dnsmasq.c:456 dnsmasq.c:1228
+#, fuzzy, c-format
+msgid "UBus error: %s"
+msgstr "Erreur DBus : %s"
+
+#: dnsmasq.c:459
 #, fuzzy
 msgid "UBus not available: set HAVE_UBUS in src/config.h"
 msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
 
-#: dnsmasq.c:459
+#: dnsmasq.c:489
 #, c-format
 msgid "unknown user or group: %s"
 msgstr "utilisateur ou groupe inconnu : %s"
 
-#: dnsmasq.c:535
+#: dnsmasq.c:565
 #, c-format
 msgid "process is missing required capability %s"
 msgstr ""
 
-#: dnsmasq.c:567
+#: dnsmasq.c:597
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr "Ne peut effectuer un 'chdir' à la racine du système de fichier : %s"
 
-#: dnsmasq.c:815
+#: dnsmasq.c:845
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr "démarrage avec le DNS désactivé (version %s)"
 
-#: dnsmasq.c:820
+#: dnsmasq.c:850
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "demarré, version %s (taille de cache %d)"
 
-#: dnsmasq.c:822
+#: dnsmasq.c:852
 msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
 msgstr ""
 
-#: dnsmasq.c:825
+#: dnsmasq.c:855
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "démarrage avec le cache désactivé (version %s)"
 
-#: dnsmasq.c:828
+#: dnsmasq.c:858
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:831
+#: dnsmasq.c:861
 #, c-format
 msgid "compile time options: %s"
 msgstr "options à la compilation : %s"
 
-#: dnsmasq.c:840
+#: dnsmasq.c:870
 msgid "DBus support enabled: connected to system bus"
 msgstr "Support DBus autorisé : connecté au bus système"
 
-#: dnsmasq.c:842
+#: dnsmasq.c:872
 msgid "DBus support enabled: bus connection pending"
 msgstr "Support DBus autorisé : connexion au bus en attente"
 
-#: dnsmasq.c:850
+#: dnsmasq.c:880
 #, fuzzy
 msgid "UBus support enabled: connected to system bus"
 msgstr "Support DBus autorisé : connecté au bus système"
 
-#: dnsmasq.c:852
+#: dnsmasq.c:882
 #, fuzzy
 msgid "UBus support enabled: bus connection pending"
 msgstr "Support DBus autorisé : connexion au bus en attente"
 
-#: dnsmasq.c:872
+#: dnsmasq.c:902
 msgid "DNSSEC validation enabled but all unsigned answers are trusted"
 msgstr ""
 
-#: dnsmasq.c:874
+#: dnsmasq.c:904
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:878
+#: dnsmasq.c:908
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:881
+#: dnsmasq.c:911
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:884
+#: dnsmasq.c:914
 #, c-format
 msgid "configured with trust anchor for %s keytag %u"
 msgstr ""
 
-#: dnsmasq.c:890
+#: dnsmasq.c:920
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "Impossible de changer pour l'utilisateur %s : %s"
 
-#: dnsmasq.c:894
+#: dnsmasq.c:924
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "active l'option --bind-interfaces à cause de limitations dans le système d'exploitation"
 
-#: dnsmasq.c:906
+#: dnsmasq.c:936
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "attention : l'interface %s n'existe pas actuellement"
 
-#: dnsmasq.c:911
+#: dnsmasq.c:941
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr "attention : l'option « resolv-file » sera ignorée car « no-resolv » a été spécifié"
 
 #
-#: dnsmasq.c:914
+#: dnsmasq.c:944
 msgid "warning: no upstream servers configured"
 msgstr "attention : aucun serveur amont n'est configuré"
 
-#: dnsmasq.c:918
+#: dnsmasq.c:948
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr "mode asynchrone d'écriture de traces, la taille maximum de la queue est de %d messages."
 
-#: dnsmasq.c:939
+#: dnsmasq.c:969
 msgid "IPv6 router advertisement enabled"
 msgstr "annonces de routeur IPv6 activées"
 
-#: dnsmasq.c:944
+#: dnsmasq.c:974
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "root is "
 msgstr "root est"
 
 #
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "enabled"
 msgstr "activé"
 
-#: dnsmasq.c:960
+#: dnsmasq.c:993
 msgid "secure mode"
 msgstr "mode sécurisé"
 
-#: dnsmasq.c:961
+#: dnsmasq.c:994
 #, fuzzy
 msgid "single port mode"
 msgstr "numéro de port invalide"
 
-#: dnsmasq.c:964
+#: dnsmasq.c:997
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:968
+#: dnsmasq.c:1001
 #, fuzzy, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr "répertoire TFTP %s inaccessible : %s"
 
-#: dnsmasq.c:994
+#: dnsmasq.c:1027
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr "le nombre maximum de transferts TFTP simultanés sera restreint à %d"
 
-#: dnsmasq.c:1173
+#: dnsmasq.c:1204
 msgid "connected to system DBus"
 msgstr "connecté au systeme DBus"
 
-#: dnsmasq.c:1345
+#: dnsmasq.c:1225
+#, fuzzy
+msgid "connected to system UBus"
+msgstr "connecté au systeme DBus"
+
+#: dnsmasq.c:1391
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr "Ne peut se lancer en tâche de fond : %s"
 
-#: dnsmasq.c:1349
+#: dnsmasq.c:1395
 #, c-format
 msgid "failed to create helper: %s"
 msgstr "impossible de créer le 'helper' : %s"
 
-#: dnsmasq.c:1353
+#: dnsmasq.c:1399
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr "impossible de configurer la capacité %s"
 
-#: dnsmasq.c:1357
+#: dnsmasq.c:1403
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "Impossible de changer l'identifiant utilisateur pour %s : %s"
 
-#: dnsmasq.c:1361
+#: dnsmasq.c:1407
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "Impossible de changer l'identifiant de groupe pour %s : %s"
 
-#: dnsmasq.c:1365
+#: dnsmasq.c:1411
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "impossible de lire le fichier de PID %s : %s"
 
-#: dnsmasq.c:1369
+#: dnsmasq.c:1415
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr "Ne peut ouvrir le fichier de log %s : %s"
 
 #
-#: dnsmasq.c:1373
+#: dnsmasq.c:1419
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr "impossible de charger le script Lua : %s"
 
-#: dnsmasq.c:1377
+#: dnsmasq.c:1423
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr "répertoire TFTP %s inaccessible : %s"
 
-#: dnsmasq.c:1381
+#: dnsmasq.c:1427
 #, fuzzy, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "ne peut ouvrir ou créer le fichiers de baux %s : %s"
 
-#: dnsmasq.c:1465
+#: dnsmasq.c:1511
 #, c-format
 msgid "script process killed by signal %d"
 msgstr "Le script a été terminé par le signal %d"
 
-#: dnsmasq.c:1469
+#: dnsmasq.c:1515
 #, c-format
 msgid "script process exited with status %d"
 msgstr "Le script s'est terminé avec le statut %d"
 
-#: dnsmasq.c:1473
+#: dnsmasq.c:1519
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr "impossible d'exécuter à %s : %s"
 
-#: dnsmasq.c:1513
+#: dnsmasq.c:1559
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
+#: dnsmasq.c:1594 dnssec.c:160 dnssec.c:204
 #, fuzzy, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "impossible de lire le fichier de PID %s : %s"
 
-#: dnsmasq.c:1560
+#: dnsmasq.c:1606
 msgid "exiting on receipt of SIGTERM"
 msgstr "sortie sur réception du signal SIGTERM"
 
-#: dnsmasq.c:1588
+#: dnsmasq.c:1634
 #, c-format
 msgid "failed to access %s: %s"
 msgstr "impossible d'accéder à %s : %s"
 
-#: dnsmasq.c:1618
+#: dnsmasq.c:1664
 #, c-format
 msgid "reading %s"
 msgstr "Lecture de %s"
 
-#: dnsmasq.c:1629
+#: dnsmasq.c:1675
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr "aucun serveur trouvé dans %s, va réessayer"
@@ -1778,27 +1889,27 @@ msgstr "Paquet DHCP re
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:471
+#: dhcp.c:473
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:526
+#: dhcp.c:530
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "La plage d'adresses DHCP %s -- %s n'est pas cohérente avec le masque de réseau %s"
 
-#: dhcp.c:914
+#: dhcp.c:918
 #, c-format
 msgid "bad line at %s line %d"
 msgstr "mauvaise ligne dans %s ligne %d"
 
-#: dhcp.c:957
+#: dhcp.c:961
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr "ignore %s à la ligne %d : duplication de nom ou d'adresse IP"
 
-#: dhcp.c:1100 rfc3315.c:2139
+#: dhcp.c:1105 rfc3315.c:2182
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr "Relais DHCP %s -> %s"
@@ -1843,8 +1954,8 @@ msgid "lease-init script returned exit code %s"
 msgstr "le script lease-init a retourné le code %s"
 
 #: lease.c:381
-#, c-format
-msgid "failed to write %s: %s (retry in %us)"
+#, fuzzy, c-format
+msgid "failed to write %s: %s (retry in %u s)"
 msgstr "impossible de lire %s : %s (prochain essai dans %us)"
 
 #: lease.c:955
@@ -1852,203 +1963,203 @@ msgstr "impossible de lire %s : %s (prochain essai dans %us)"
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr "Le domaine %s est ignoré pour l'hôte DHCP %s"
 
-#: rfc2131.c:372
-#, c-format
-msgid "no address range available for DHCP request %s %s"
-msgstr "pas de plage d'adresse disponible pour la requête DHCP %s %s"
-
-#: rfc2131.c:373
+#: rfc2131.c:378
 msgid "with subnet selector"
 msgstr "avec sélecteur de sous-reseau"
 
-#: rfc2131.c:373
+#: rfc2131.c:383
 msgid "via"
 msgstr "par l'intermédiaire de"
 
-#: rfc2131.c:385
+#: rfc2131.c:389
+#, c-format
+msgid "no address range available for DHCP request %s %s"
+msgstr "pas de plage d'adresse disponible pour la requête DHCP %s %s"
+
+#: rfc2131.c:403
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "%u sous-réseaux DHCP disponibles : %s/%s"
 
-#: rfc2131.c:388 rfc3315.c:319
+#: rfc2131.c:409 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr "%u la gamme DHCP disponible est : %s -- %s"
 
-#: rfc2131.c:499
+#: rfc2131.c:521
 #, c-format
 msgid "%u vendor class: %s"
 msgstr "%u Classe de vendeur ('Vendor Class') : %s"
 
-#: rfc2131.c:501
+#: rfc2131.c:523
 #, c-format
 msgid "%u user class: %s"
 msgstr "%u Classe d'utilisateur : %s"
 
-#: rfc2131.c:535
+#: rfc2131.c:557
 msgid "disabled"
 msgstr "désactivé"
 
-#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
-#: rfc3315.c:1097
+#: rfc2131.c:598 rfc2131.c:1087 rfc2131.c:1532 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1121
 msgid "ignored"
 msgstr "ignoré"
 
-#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
+#: rfc2131.c:613 rfc2131.c:1333 rfc3315.c:867
 msgid "address in use"
 msgstr "adresse déjà utilisée"
 
-#: rfc2131.c:605 rfc2131.c:1119
+#: rfc2131.c:627 rfc2131.c:1141
 msgid "no address available"
 msgstr "pas d'adresse disponible"
 
-#: rfc2131.c:612 rfc2131.c:1273
+#: rfc2131.c:634 rfc2131.c:1295
 msgid "wrong network"
 msgstr "mauvais réseau"
 
-#: rfc2131.c:627
+#: rfc2131.c:649
 msgid "no address configured"
 msgstr "pas d'adresse configurée"
 
-#: rfc2131.c:633 rfc2131.c:1323
+#: rfc2131.c:655 rfc2131.c:1346
 msgid "no leases left"
 msgstr "plus aucun bail disponible"
 
-#: rfc2131.c:734 rfc3315.c:499
+#: rfc2131.c:756 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr "le client %u fourni le nom : %s"
 
-#: rfc2131.c:864
+#: rfc2131.c:885
 msgid "PXE BIS not supported"
 msgstr "Service PXE BIS (Boot Integrity Services) non supporté"
 
-#: rfc2131.c:1032 rfc3315.c:1197
+#: rfc2131.c:1054 rfc3315.c:1222
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "désactive l'adresse statique DHCP %s pour %s"
 
-#: rfc2131.c:1053
+#: rfc2131.c:1075
 msgid "unknown lease"
 msgstr "bail inconnu"
 
-#: rfc2131.c:1088
+#: rfc2131.c:1110
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr "L'adresse statique %s ne sera pas utilisée car un bail est déjà attribué à %s"
 
-#: rfc2131.c:1098
+#: rfc2131.c:1120
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr "L'adresse statique %s ne sera pas utilisée car elle est utilisée par le serveur ou un relai"
 
-#: rfc2131.c:1101
+#: rfc2131.c:1123
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr "L'adresse statique %s ne sera pas utilisée car elle a préalablement été refusée"
 
-#: rfc2131.c:1117 rfc2131.c:1316
+#: rfc2131.c:1139 rfc2131.c:1339
 msgid "no unique-id"
 msgstr "pas d'identifiant unique"
 
-#: rfc2131.c:1209
+#: rfc2131.c:1231
 msgid "wrong server-ID"
 msgstr "mauvais identifiant de serveur"
 
-#: rfc2131.c:1228
+#: rfc2131.c:1250
 msgid "wrong address"
 msgstr "mauvaise adresse"
 
-#: rfc2131.c:1246 rfc3315.c:961
+#: rfc2131.c:1268 rfc3315.c:975
 msgid "lease not found"
 msgstr "bail non trouvé"
 
-#: rfc2131.c:1281
+#: rfc2131.c:1303
 msgid "address not available"
 msgstr "adresse non disponible"
 
-#: rfc2131.c:1292
+#: rfc2131.c:1314
 msgid "static lease available"
 msgstr "bail statique disponible"
 
-#: rfc2131.c:1296
+#: rfc2131.c:1318
 msgid "address reserved"
 msgstr "adresse reservée"
 
-#: rfc2131.c:1304
+#: rfc2131.c:1327
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr "abandon du bail de %s pour %s"
 
-#: rfc2131.c:1845
+#: rfc2131.c:1866
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr "%u nom de fichier 'bootfile' : %s"
 
-#: rfc2131.c:1854
+#: rfc2131.c:1875
 #, c-format
 msgid "%u server name: %s"
 msgstr "%u nom du serveur : %s"
 
-#: rfc2131.c:1862
+#: rfc2131.c:1885
 #, c-format
 msgid "%u next server: %s"
 msgstr "%u serveur suivant : %s"
 
-#: rfc2131.c:1865
+#: rfc2131.c:1889
 #, c-format
 msgid "%u broadcast response"
 msgstr "%u réponse broadcast"
 
-#: rfc2131.c:1928
+#: rfc2131.c:1952
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "Impossible d'envoyer l'option DHCP/BOOTP %d : pas assez d'espace dans le paquet"
 
-#: rfc2131.c:2219
+#: rfc2131.c:2262
 msgid "PXE menu too large"
 msgstr "menu PXE trop grand"
 
-#: rfc2131.c:2358 rfc3315.c:1470
+#: rfc2131.c:2425 rfc3315.c:1511
 #, c-format
 msgid "%u requested options: %s"
 msgstr "%u options demandées : %s"
 
-#: rfc2131.c:2675
+#: rfc2131.c:2742
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr "ne peux envoyer l'option RFC3925 : trop d'options pour le numéro d'entreprise %d"
 
-#: rfc2131.c:2738
+#: rfc2131.c:2805
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:76
+#: netlink.c:93
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "ne peux lier une socket netlink : %s"
 
-#: netlink.c:352
+#: netlink.c:377
 #, c-format
 msgid "netlink returns error: %s"
 msgstr "Erreur netlink : %s"
 
-#: dbus.c:438
+#: dbus.c:434
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:443
+#: dbus.c:439
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:717
+#: dbus.c:713
 msgid "setting upstream servers from DBus"
 msgstr "configuration des serveurs amonts à partir de DBus"
 
-#: dbus.c:764
+#: dbus.c:760
 msgid "could not register a DBus message handler"
 msgstr "ne peut enregistrer une routine de traitement des messages DBus"
 
@@ -2075,31 +2186,36 @@ msgstr ""
 msgid "lease() function missing in Lua script"
 msgstr "la fonction lease() est absente du script Lua"
 
-#: tftp.c:347
+#: tftp.c:349
 msgid "unable to get free port for TFTP"
 msgstr "impossible d'obtenir un port libre pour TFTP"
 
-#: tftp.c:363
+#: tftp.c:365
 #, c-format
 msgid "unsupported request from %s"
 msgstr "requête de %s non supportée"
 
-#: tftp.c:510
+#: tftp.c:512
 #, c-format
 msgid "file %s not found"
 msgstr "fichier %s non trouvé"
 
-#: tftp.c:628
+#: tftp.c:602
+#, c-format
+msgid "ignoring packet from %s (TID mismatch)"
+msgstr ""
+
+#: tftp.c:646
 #, c-format
 msgid "failed sending %s to %s"
 msgstr "impossible d'envoyer %s à %s"
 
-#: tftp.c:628
+#: tftp.c:646
 #, c-format
 msgid "sent %s to %s"
 msgstr "envoyé %s à %s"
 
-#: tftp.c:678
+#: tftp.c:696
 #, c-format
 msgid "error %d %s received from %s"
 msgstr "erreur %d %s reçu de %s"
@@ -2114,7 +2230,7 @@ msgstr "d
 msgid "log failed: %s"
 msgstr "trace perdue : %s"
 
-#: log.c:471
+#: log.c:477
 msgid "FAILED to start up"
 msgstr "IMPOSSIBLE de démarrer"
 
@@ -2167,11 +2283,11 @@ msgstr "%u MAC adresse du client : %s"
 msgid "address unavailable"
 msgstr "adresse non disponible"
 
-#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1272
 msgid "success"
 msgstr "réussi"
 
-#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913 rfc3315.c:1047
 msgid "no addresses available"
 msgstr "pas d'adresse disponible"
 
@@ -2179,114 +2295,114 @@ msgstr "pas d'adresse disponible"
 msgid "not on link"
 msgstr "pas sur ce lien"
 
-#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
+#: rfc3315.c:979 rfc3315.c:1180 rfc3315.c:1261
 msgid "no binding found"
 msgstr "aucune liaison trouvée"
 
-#: rfc3315.c:1002
+#: rfc3315.c:1016
 msgid "deprecated"
 msgstr "obsolète"
 
-#: rfc3315.c:1007
+#: rfc3315.c:1023
 msgid "address invalid"
 msgstr "adresse non valide"
 
-#: rfc3315.c:1057 rfc3315.c:1059
+#: rfc3315.c:1081 rfc3315.c:1083
 msgid "confirm failed"
 msgstr "confirmation d'échec"
 
-#: rfc3315.c:1074
+#: rfc3315.c:1098
 msgid "all addresses still on link"
 msgstr "toutes les adresses sont toujours sur le lien"
 
-#: rfc3315.c:1165
+#: rfc3315.c:1189
 msgid "release received"
 msgstr "libération reçue"
 
-#: rfc3315.c:2130
+#: rfc3315.c:2173
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr "Impossible de faire du multicast au server DHCPv6 sans interface valide"
 
-#: dhcp-common.c:145
+#: dhcp-common.c:154
 #, c-format
 msgid "Ignoring duplicate dhcp-option %d"
 msgstr "L'option dhcp-option redondante %d sera ignorée"
 
-#: dhcp-common.c:222
+#: dhcp-common.c:231
 #, c-format
 msgid "%u tags: %s"
 msgstr "%u options: %s"
 
-#: dhcp-common.c:444
+#: dhcp-common.c:451
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr "%s a plus d'une adresse dans le fichier d'hôte, utilisation de %s pour le DHCP."
 
-#: dhcp-common.c:478
+#: dhcp-common.c:485
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "adresse IP %s (%s) dupliquée dans la directive dhcp-config."
 
-#: dhcp-common.c:542
+#: dhcp-common.c:549
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "impossible de déclarer SO_BINDTODEVICE sur la socket DHCP : %s"
 
-#: dhcp-common.c:665
+#: dhcp-common.c:672
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr "Options DHCP connues :\n"
 
-#: dhcp-common.c:676
+#: dhcp-common.c:683
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr "Options DHCPv6 connues :\n"
 
-#: dhcp-common.c:873
+#: dhcp-common.c:880
 msgid ", prefix deprecated"
 msgstr ", préfixe obsolète"
 
-#: dhcp-common.c:876
+#: dhcp-common.c:883
 #, c-format
 msgid ", lease time "
 msgstr ", durée de bail "
 
-#: dhcp-common.c:918
+#: dhcp-common.c:925
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr "%s sans état (stateless) sur %s%.0s%.0s%s"
 
-#: dhcp-common.c:920
+#: dhcp-common.c:927
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "%s, baux statiques seulement sur %.0s%s%s%.0s"
 
-#: dhcp-common.c:922
+#: dhcp-common.c:929
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr "%s, proxy sur le sous-réseau %.0s%s%.0s"
 
-#: dhcp-common.c:923
+#: dhcp-common.c:930
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "%s, plage d'adresses IP %s -- %s%s%.0s"
 
-#: dhcp-common.c:936
+#: dhcp-common.c:943
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr "noms IPv6 dérivés de DHCPv4 sur %s%s"
 
-#: dhcp-common.c:939
+#: dhcp-common.c:946
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr "annonces de routeurs sur %s%s"
 
-#: dhcp-common.c:950
+#: dhcp-common.c:957
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr "Relais DHCP de %s à %s via %s"
 
-#: dhcp-common.c:952
+#: dhcp-common.c:959
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr "Relais DHCP de %s à %s"
@@ -2296,31 +2412,119 @@ msgstr "Relais DHCP de %s 
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "ne peut créer la socket ICMPv6: %s"
 
-#: auth.c:439
+#: auth.c:464
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr "la requête de transfert de zone en provenance de %s est ignorée"
 
-#: ipset.c:95
-#, c-format
-msgid "failed to find kernel version: %s"
-msgstr "impossible de trouver la version de noyau : %s"
-
-#: ipset.c:114
+#: ipset.c:99
 #, c-format
 msgid "failed to create IPset control socket: %s"
 msgstr "impossible de créer une socket de contrôle IPset : %s"
 
-#: ipset.c:226
+#: ipset.c:211
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "impossible de lire le fichier de PID %s : %s"
 
+#: pattern.c:29
+#, c-format
+msgid "[pattern.c:%d] Assertion failure: %s"
+msgstr ""
+
+#: pattern.c:142
+#, c-format
+msgid "Invalid DNS name: Invalid character %c."
+msgstr ""
+
+#: pattern.c:151
+msgid "Invalid DNS name: Empty label."
+msgstr ""
+
+#: pattern.c:156
+msgid "Invalid DNS name: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:170
+msgid "Invalid DNS name: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:176
+#, c-format
+msgid "Invalid DNS name: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:184
+#, c-format
+msgid "Invalid DNS name: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:189
+msgid "Invalid DNS name: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:199
+msgid "Invalid DNS name: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:204
+#, c-format
+msgid "DNS name has invalid length (%zu)."
+msgstr ""
+
+#: pattern.c:258
+#, c-format
+msgid "Invalid DNS name pattern: Invalid character %c."
+msgstr ""
+
+#: pattern.c:267
+msgid "Invalid DNS name pattern: Empty label."
+msgstr ""
+
+#: pattern.c:272
+msgid "Invalid DNS name pattern: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:285
+msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+msgstr ""
+
+#: pattern.c:295
+msgid "Invalid DNS name pattern: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:301
+#, c-format
+msgid "Invalid DNS name pattern: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:309
+#, c-format
+msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:314
+msgid "Invalid DNS name pattern: Wildcard within final two labels."
+msgstr ""
+
+#: pattern.c:319
+msgid "Invalid DNS name pattern: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:329
+msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:334
+#, c-format
+msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
+msgstr ""
+
 #: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: dnssec.c:902
+#: dnssec.c:1014
 #, c-format
 msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
 msgstr ""
@@ -2352,7 +2556,7 @@ msgstr ""
 
 #: tables.c:101
 #, fuzzy, c-format
-msgid "IPset: error:%s"
+msgid "IPset: error: %s"
 msgstr "Erreur DBus : %s"
 
 #: tables.c:108
@@ -2415,56 +2619,54 @@ msgstr "Ne peut pas lire %s : %s"
 msgid "bad header in %s"
 msgstr "adresse déjà utilisée"
 
-#: dump.c:201
+#: dump.c:205
 #, fuzzy
 msgid "failed to write packet dump"
 msgstr "impossible d'envoyer le paquet : %s"
 
-#: dump.c:203
+#: dump.c:207
 #, c-format
 msgid "dumping UDP packet %u mask 0x%04x"
 msgstr ""
 
-#: ubus.c:52
+#: ubus.c:79
 #, c-format
 msgid "UBus subscription callback: %s subscriber(s)"
 msgstr ""
 
-#: ubus.c:73
+#: ubus.c:99
 #, fuzzy, c-format
 msgid "Cannot reconnect to UBus: %s"
 msgstr "Ne peut ouvrir le fichier de log %s : %s"
 
-#: ubus.c:89
-msgid "Cannot initialize UBus: connection failed"
-msgstr ""
-
-#: ubus.c:102
-#, fuzzy, c-format
-msgid "Cannot add object to UBus: %s"
-msgstr "Ne peut ouvrir le fichier de log %s : %s"
-
-#: ubus.c:112
-#, fuzzy
-msgid "Connected to system UBus"
-msgstr "connecté au systeme DBus"
-
-#: ubus.c:122
+#: ubus.c:135
 msgid "Cannot set UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:142
+#: ubus.c:155
 msgid "Cannot poll UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:155
+#: ubus.c:168
 msgid "Disconnecting from UBus"
 msgstr ""
 
-#: ubus.c:199
-#, fuzzy, c-format
-msgid "Failed to send UBus event: %s"
-msgstr "impossible d'envoyer le paquet : %s"
+#: ubus.c:179 ubus.c:326
+#, c-format
+msgid "UBus command failed: %d (%s)"
+msgstr ""
+
+#: hash-questions.c:40
+msgid "Failed to create SHA-256 hash object"
+msgstr ""
+
+#, fuzzy
+#~ msgid "Cannot add object to UBus: %s"
+#~ msgstr "Ne peut ouvrir le fichier de log %s : %s"
+
+#, fuzzy
+#~ msgid "Failed to send UBus event: %s"
+#~ msgstr "impossible d'envoyer le paquet : %s"
 
 #~ msgid "Specify DHCPv6 prefix class"
 #~ msgstr "Spécifie le préfixe de classe DHCPv6"
index 5b74aa8..11aa042 100644 (file)
--- a/po/id.po
+++ b/po/id.po
@@ -15,895 +15,929 @@ msgstr ""
 "Content-Type: text/plain; charset=ASCII\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: cache.c:559
+#: cache.c:572
 msgid "Internal error in cache."
 msgstr ""
 
 # OK
-#: cache.c:1081
+#: cache.c:1094
 #, fuzzy, c-format
 msgid "failed to load names from %s: %s"
 msgstr "gagal memuat nama-nama dari %s: %s"
 
 # OK
-#: cache.c:1103 dhcp.c:927
+#: cache.c:1116 dhcp.c:931
 #, fuzzy, c-format
 msgid "bad address at %s line %d"
 msgstr "kesalahan nama pada %s baris %d"
 
 # OK
-#: cache.c:1156 dhcp.c:943
+#: cache.c:1169 dhcp.c:947
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "kesalahan nama pada %s baris %d"
 
 # OK
-#: cache.c:1167 dhcp.c:1018
+#: cache.c:1180 dhcp.c:1022
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: cache.c:1283
+#: cache.c:1296
 msgid "cleared cache"
 msgstr "cache telah dihapus"
 
-#: cache.c:1345
+#: cache.c:1358
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1391
+#: cache.c:1404
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
 # OK
-#: cache.c:1415
+#: cache.c:1428
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "tidak memberikan nama %s kepada lease DHCP %s karena nama telah ada dalam %sdengan alamat %s"
 
-#: cache.c:1663
+#: cache.c:1674
 #, c-format
 msgid "time %lu"
 msgstr ""
 
 # OK
-#: cache.c:1664
+#: cache.c:1675
 #, fuzzy, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "ukuran cache %d, %d/%d penyisipan cache menimpa cache yang belum kadaluwarsa"
 
-#: cache.c:1666
+#: cache.c:1677
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1669
+#: cache.c:1680
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1694
+#: cache.c:1702
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
 
 # OK
-#: util.c:47
+#: util.c:51
 #, fuzzy, c-format
 msgid "failed to seed the random number generator: %s"
 msgstr "gagal mendengarkan di socket: %s"
 
 # OK
-#: util.c:224
+#: util.c:228
 #, fuzzy
 msgid "failed to allocate memory"
 msgstr "gagal memuat %S: %m"
 
 # OK
-#: util.c:281 option.c:641
+#: util.c:285 option.c:665
 msgid "could not get memory"
 msgstr "tidak bisa mendapatkan memory"
 
 # OK
-#: util.c:302
+#: util.c:306
 #, fuzzy, c-format
 msgid "cannot create pipe: %s"
 msgstr "tidak bisa membaca %s: %s"
 
 # OK
-#: util.c:310
+#: util.c:314
 #, fuzzy, c-format
 msgid "failed to allocate %d bytes"
 msgstr "gagal memuat %S: %m"
 
 # OK
-#: util.c:506
+#: util.c:520
 #, c-format
 msgid "infinite"
 msgstr "tak terbatas"
 
 # OK
-#: option.c:358
+#: util.c:808
+#, fuzzy, c-format
+msgid "failed to find kernel version: %s"
+msgstr "gagal mem-bind socket server DHCP: %s"
+
+# OK
+#: option.c:372
 msgid "Specify local address(es) to listen on."
 msgstr "Tentukan alamat lokal untuk mendengarkan."
 
 # OK
-#: option.c:359
+#: option.c:373
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Menghasilkan ipaddr untuk semua host dalam domain yang dipilih."
 
 # OK
-#: option.c:360
+#: option.c:374
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Fake pencarian balik untuk alamat private sesuai dengan RFC1918."
 
 # OK
-#: option.c:361
+#: option.c:375
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Perlakukan ipaddr sebagai NXDOMAIN (mengalahkan wildcard Verisign)."
 
 # OK
-#: option.c:362
+#: option.c:376
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Tentukan ukuran cache, dalam jumlah isian (default %s)."
 
 # OK
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Tentukan file konfigurasi (default %s)."
 
 # OK
-#: option.c:364
+#: option.c:378
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "JANGAN berjalan di background: berjalan dalam modus debug."
 
 # OK
-#: option.c:365
+#: option.c:379
 msgid "Do NOT forward queries with no domain part."
 msgstr "JANGAN teruskan permintaan tanpa bagian domain."
 
 # OK
-#: option.c:366
+#: option.c:380
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Mengembalikan record MX untuk diri sendiri host-host lokal."
 
 # OK
-#: option.c:367
+#: option.c:381
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Melengkapi nama-nama di /etc/hosts dengan akhiran domain."
 
 # OK
-#: option.c:368
+#: option.c:382
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "Jangan meneruskan permintaan DNS spurious dari host-host Windows."
 
 # OK
-#: option.c:369
+#: option.c:383
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Bolehkan DHCP dalam jangkauan yang diberikan dengan durasi lease."
 
 # OK
-#: option.c:370
+#: option.c:384
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Ubah ke group ini setelah mulai (default %s)."
 
 # OK
-#: option.c:371
+#: option.c:385
 msgid "Set address or hostname for a specified machine."
 msgstr "Setel alamat atau nama host untuk mesin yang disebutkan."
 
 # OK
-#: option.c:372
+#: option.c:386
 #, fuzzy
 msgid "Read DHCP host specs from file."
 msgstr "nama MX salah"
 
-#: option.c:373
+#: option.c:387
 msgid "Read DHCP option specs from file."
 msgstr ""
 
 # OK
-#: option.c:374
+#: option.c:388
 #, fuzzy
 msgid "Read DHCP host specs from a directory."
 msgstr "nama MX salah"
 
 # OK
-#: option.c:375
+#: option.c:389
 #, fuzzy
 msgid "Read DHCP options from a directory."
 msgstr "nama MX salah"
 
-#: option.c:376
+#: option.c:390
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
 # OK
-#: option.c:377
+#: option.c:391
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "JANGAN muat file %s."
 
 # OK
-#: option.c:378
+#: option.c:392
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Sebutkan sebuah file hosts yang harus dibaca sebagai tambahan untuk %s."
 
 # OK
-#: option.c:379
+#: option.c:393
 #, fuzzy
 msgid "Read hosts files from a directory."
 msgstr "nama MX salah"
 
 # OK
-#: option.c:380
+#: option.c:394
 msgid "Specify interface(s) to listen on."
 msgstr "Sebutkan antarmuka untuk mendengarkan."
 
 # OK
-#: option.c:381
+#: option.c:395
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Sebutkan antarmuka untuk TIDAK mendengarkan."
 
 # OK
-#: option.c:382
+#: option.c:396
 #, fuzzy
 msgid "Map DHCP user class to tag."
 msgstr "Petakan kelas user DHCP ke setelan yang dipilih."
 
-#: option.c:383
+#: option.c:397
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:384
+#: option.c:398
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
+#: option.c:400
+msgid "Specify vendor class to match for PXE requests."
+msgstr ""
+
 # OK
-#: option.c:386
+#: option.c:401
 #, fuzzy
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Jangan menggunakan DHCP untuk host-host yang dipilih."
 
 # OK
-#: option.c:387
+#: option.c:402
 #, fuzzy
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Jangan menggunakan DHCP untuk host-host yang dipilih."
 
 # OK
-#: option.c:388
+#: option.c:403
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "JANGAN berjalan di background, jangan berjalan dalam modus debug."
 
 # OK
-#: option.c:389
+#: option.c:404
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Berpikir bahwa kita satu-satunya DHCP server dalam jaringan."
 
 # OK
-#: option.c:390
+#: option.c:405
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Sebutkan lokasi untuk menyimpan lease DHCP (default %s)."
 
 # OK
-#: option.c:391
+#: option.c:406
 msgid "Return MX records for local hosts."
 msgstr "Kembalikan rekord MX untuk host-host lokal."
 
 # OK
-#: option.c:392
+#: option.c:407
 msgid "Specify an MX record."
 msgstr "Sebutkan sebuah rekord MX."
 
 # OK
-#: option.c:393
+#: option.c:408
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Sebutkan pilihan-pilihan BOOTP untuk DHCP server."
 
-#: option.c:394
+#: option.c:409
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "Jangan kumpulkan file %s, muat kembali saat SIGHUP."
 
 # OK
-#: option.c:395
+#: option.c:410
 msgid "Do NOT cache failed search results."
 msgstr "JANGAN menyimpan hasil pencarian yang gagal."
 
 # OK
-#: option.c:396
+#: option.c:411
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Gunakan secara ketat namaserver yang disebutkan sesuai urutan di %s."
 
 # OK
-#: option.c:397
+#: option.c:412
 #, fuzzy
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Setel pilihan-pilihan tambahan yang akan disetel untuk klien-klien DHCP."
 
-#: option.c:398
+#: option.c:413
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
 # OK
-#: option.c:399
+#: option.c:414
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Sebutkan port untuk mendengarkan permintaan DNS (default port 53)."
 
 # OK
-#: option.c:400
+#: option.c:415
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Ukuran maksimum paket UDP yang didukung untuk EDNS.0 (default %s)."
 
 # OK
-#: option.c:401
+#: option.c:416
 #, fuzzy
 msgid "Log DNS queries."
 msgstr "Permintaan log."
 
 # OK
-#: option.c:402
+#: option.c:417
 #, fuzzy
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Paksa port asal untuk permintaan ke atas."
 
 # OK
-#: option.c:403
+#: option.c:418
 msgid "Do NOT read resolv.conf."
 msgstr "JANGAN baca resolv.conf."
 
 # OK
-#: option.c:404
+#: option.c:419
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Sebutkan path ke resolv.conf (default %s)."
 
 # OK
-#: option.c:405
+#: option.c:420
 #, fuzzy
 msgid "Specify path to file with server= options"
 msgstr "Sebutkan path file PID. (default %s)."
 
 # OK
-#: option.c:406
+#: option.c:421
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Sebutkan alamat-alamat server di atas, boleh dilengkapi dengan nama domain."
 
 # OK
-#: option.c:407
+#: option.c:422
 #, fuzzy
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Sebutkan alamat-alamat server di atas, boleh dilengkapi dengan nama domain."
 
 # OK
-#: option.c:408
+#: option.c:423
 msgid "Never forward queries to specified domains."
 msgstr "JANGAN pernah meneruskan permintaan ke domain yang disebutkan."
 
 # OK
-#: option.c:409
+#: option.c:424
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Sebutkan domain yang digunakan dalam lease DHCP."
 
 # OK
-#: option.c:410
+#: option.c:425
 msgid "Specify default target in an MX record."
 msgstr "Sebutkan tujuan default dalam rekord MX."
 
 # OK
-#: option.c:411
+#: option.c:426
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Sebutkan time-to-live dalam detik untuk jawaban dari /etc/hosts."
 
 # OK
-#: option.c:412
+#: option.c:427
 #, fuzzy
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Sebutkan time-to-live dalam detik untuk jawaban dari /etc/hosts."
 
 # OK
-#: option.c:413
+#: option.c:428
 #, fuzzy
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Sebutkan time-to-live dalam detik untuk jawaban dari /etc/hosts."
 
 # OK
-#: option.c:414
+#: option.c:429
 #, fuzzy
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Sebutkan time-to-live dalam detik untuk jawaban dari /etc/hosts."
 
 # OK
-#: option.c:415
+#: option.c:430
 #, fuzzy
 msgid "Specify time-to-live floor for cache."
 msgstr "Sebutkan time-to-live dalam detik untuk jawaban dari /etc/hosts."
 
 # OK
-#: option.c:416
+#: option.c:431
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Ubah ke user ini setelah mulai. (default %s)."
 
 # OK
-#: option.c:417
+#: option.c:432
 #, fuzzy
 msgid "Map DHCP vendor class to tag."
 msgstr "Memetakan kelas vendor DHCP ke daftar pilihan."
 
 # OK
-#: option.c:418
+#: option.c:433
 msgid "Display dnsmasq version and copyright information."
 msgstr "Menampilkan versi dan informasi hak cipta dnsmasq."
 
 # OK
-#: option.c:419
+#: option.c:434
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Terjemahkan alamat-alamat IPv4 dari server-server di atas."
 
 # OK
-#: option.c:420
+#: option.c:435
 msgid "Specify a SRV record."
 msgstr "Sebutkan rekord SRV."
 
-#: option.c:421
+#: option.c:436
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
 # OK
-#: option.c:422
+#: option.c:437
 #, fuzzy, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Sebutkan path file PID. (default %s)."
 
 # OK
-#: option.c:423
+#: option.c:438
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
 
 # OK
-#: option.c:424
+#: option.c:439
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Jawab permintaan DNS berdasarkan antarmuka dimana permintaan dikirimkan."
 
 # OK
-#: option.c:425
+#: option.c:440
 msgid "Specify TXT DNS record."
 msgstr "Sebutkan rekord TXT DNS."
 
 # OK
-#: option.c:426
+#: option.c:441
 #, fuzzy
 msgid "Specify PTR DNS record."
 msgstr "Sebutkan rekord TXT DNS."
 
-#: option.c:427
+#: option.c:442
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
 # OK
-#: option.c:428
+#: option.c:443
 msgid "Bind only to interfaces in use."
 msgstr "Hanya kaitkan ke antarmuka yang sedang digunakan saja."
 
 # OK
-#: option.c:429
+#: option.c:444
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Baca informasi statik host DHCP dari %s."
 
 # OK
-#: option.c:430
+#: option.c:445
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Mungkinkan antar muka DBus untuk menyetel server-server di atas, dsb."
 
-#: option.c:431
+#: option.c:446
 msgid "Enable the UBus interface."
 msgstr ""
 
 # OK
-#: option.c:432
+#: option.c:447
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "JANGAN menyediakan DHCP pada antarmuka ini, hanya menyediakan DNS."
 
 # OK
-#: option.c:433
+#: option.c:448
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Mungkinkan alokasi alamat dinamis untuk bootp."
 
 # OK
-#: option.c:434
+#: option.c:449
 #, fuzzy
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Memetakan kelas vendor DHCP ke daftar pilihan."
 
-#: option.c:435
+#: option.c:450
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:436
+#: option.c:451
 msgid "Specify extra networks sharing a broadcast domain for DHCP"
 msgstr ""
 
-#: option.c:437
+#: option.c:452
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:438
+#: option.c:453
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:439
+#: option.c:454
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:440
+#: option.c:455
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:441
+#: option.c:456
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:442
+#: option.c:457
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
 # OK
-#: option.c:443
+#: option.c:458
 #, fuzzy
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Ubah ke user ini setelah mulai. (default %s)."
 
-#: option.c:444
+#: option.c:459
 msgid "Do not use leasefile."
 msgstr ""
 
 # OK
-#: option.c:445
+#: option.c:460
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
 
-#: option.c:446
+#: option.c:461
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:447
+#: option.c:462
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:448
+#: option.c:463
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:449
+#: option.c:464
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:450
+#: option.c:465
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:451
+#: option.c:466
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:452
+#: option.c:467
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:453
+#: option.c:468
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
 # OK
-#: option.c:454
+#: option.c:469
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
 
 # OK
-#: option.c:455
+#: option.c:470
 #, fuzzy
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
 
-#: option.c:456
+#: option.c:471
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:457
+#: option.c:472
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:458
+#: option.c:473
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:459
+#: option.c:474
 msgid "Use only one port for TFTP server."
 msgstr ""
 
-#: option.c:460
+#: option.c:475
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:461
+#: option.c:476
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:462
+#: option.c:477
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:463
+#: option.c:478
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:464
+#: option.c:479
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:465
+#: option.c:480
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:466
+#: option.c:481
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:467
+#: option.c:482
 msgid "Set tag if client provides given name."
 msgstr ""
 
-#: option.c:468
+#: option.c:483
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
 # OK
-#: option.c:469
+#: option.c:484
 #, fuzzy
 msgid "Specify NAPTR DNS record."
 msgstr "Sebutkan rekord TXT DNS."
 
-#: option.c:470
+#: option.c:485
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:471
+#: option.c:486
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:472
+#: option.c:487
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:473
+#: option.c:488
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:474
+#: option.c:489
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:475
+#: option.c:490
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:476
+#: option.c:491
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
 # OK
-#: option.c:477
+#: option.c:492
 #, fuzzy
 msgid "Prompt to send to PXE clients."
 msgstr "Setel pilihan-pilihan tambahan yang akan disetel untuk klien-klien DHCP."
 
-#: option.c:478
+#: option.c:493
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:479
+#: option.c:494
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:480
+#: option.c:495
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:481
+#: option.c:496
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
 # OK
-#: option.c:482
+#: option.c:497
 #, fuzzy
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Paksa port asal untuk permintaan ke atas."
 
 # OK
-#: option.c:483
+#: option.c:498
 #, fuzzy
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Terjemahkan alamat-alamat IPv4 dari server-server di atas."
 
-#: option.c:484
+#: option.c:499
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
 # OK
-#: option.c:485
+#: option.c:500
 #, fuzzy
 msgid "Ignore client identifier option sent by DHCP clients."
 msgstr "Setel pilihan-pilihan tambahan yang akan disetel untuk klien-klien DHCP."
 
-#: option.c:486
+#: option.c:501
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:487
+#: option.c:502
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:488
+#: option.c:503
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:489
+#: option.c:504
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
 # OK
-#: option.c:490
+#: option.c:505
 #, fuzzy
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Sebutkan sebuah rekord MX."
 
-#: option.c:491
+#: option.c:506
+msgid "Specify host record in interface subnet"
+msgstr ""
+
+#: option.c:507
 msgid "Specify certification authority authorization record"
 msgstr ""
 
 # OK
-#: option.c:492
+#: option.c:508
 #, fuzzy
 msgid "Specify arbitrary DNS resource record"
 msgstr "Sebutkan rekord TXT DNS."
 
 # OK
-#: option.c:493
+#: option.c:509
 #, fuzzy
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "antarmuka tidak dikenal %s"
 
-#: option.c:494
+#: option.c:510
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:495
+#: option.c:511
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:496
+#: option.c:512
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:497
+#: option.c:513
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:498
+#: option.c:514
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:499
+#: option.c:515
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:500
+#: option.c:516
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:501
+#: option.c:517
+msgid "Enable filtering of DNS queries with connection-track marks."
+msgstr ""
+
+#: option.c:518
+msgid "Set allowed DNS patterns for a connection-track mark."
+msgstr ""
+
+#: option.c:519
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:502
+#: option.c:520
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:503
+#: option.c:521
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:504
+#: option.c:522
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:505
+#: option.c:523
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:506
+#: option.c:524
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:507
+#: option.c:525
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:508
+#: option.c:526
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:509
+#: option.c:527
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:510
+#: option.c:528
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:511
+#: option.c:529
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:512
+#: option.c:530
+msgid "Log debugging information."
+msgstr ""
+
+#: option.c:531
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:513
+#: option.c:532
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:514
+#: option.c:533
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:515
+#: option.c:534
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:516
+#: option.c:535
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:517
+#: option.c:536
 msgid "Enables DHCPv4 Rapid Commit option."
 msgstr ""
 
-#: option.c:518
+#: option.c:537
 msgid "Path to debug packet dump file"
 msgstr ""
 
-#: option.c:519
+#: option.c:538
 msgid "Mask which packets to dump"
 msgstr ""
 
-#: option.c:520
+#: option.c:539
 msgid "Call dhcp-script when lease expiry changes."
 msgstr ""
 
+#: option.c:540
+msgid "Send Cisco Umbrella identifiers including remote IP."
+msgstr ""
+
+#: option.c:541
+msgid "Do not log routine TFTP."
+msgstr ""
+
 # OK
-#: option.c:725
+#: option.c:771
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -913,409 +947,455 @@ msgstr ""
 "\n"
 
 # OK
-#: option.c:727
+#: option.c:773
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Gunakan pilihan pendek saja pada perintah baris.\n"
 
 # OK
-#: option.c:729
+#: option.c:775
 #, fuzzy, c-format
 msgid "Valid options are:\n"
 msgstr "Pilihan yang boleh adalah:\n"
 
 # OK
-#: option.c:776 option.c:884
+#: option.c:822 option.c:933
 #, fuzzy
 msgid "bad address"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: option.c:799 option.c:803
+#: option.c:847 option.c:851
 msgid "bad port"
 msgstr "port salah"
 
-#: option.c:815 option.c:844 option.c:878
+#: option.c:864 option.c:893 option.c:927
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:839 option.c:873
+#: option.c:888 option.c:922
 msgid "interface can only be specified once"
 msgstr ""
 
 # OK
-#: option.c:852 option.c:4042
+#: option.c:901 option.c:4362
 #, fuzzy
 msgid "bad interface name"
 msgstr "nama MX salah"
 
-#: option.c:1184
+#: option.c:1192
+msgid "inappropriate vendor:"
+msgstr ""
+
+#: option.c:1199
+msgid "inappropriate encap:"
+msgstr ""
+
+#: option.c:1225
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
 # OK
-#: option.c:1198
+#: option.c:1239
 msgid "bad dhcp-option"
 msgstr "dhcp-option salah"
 
 # OK
-#: option.c:1270
+#: option.c:1317
 #, fuzzy
 msgid "bad IP address"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: option.c:1273 option.c:1412 option.c:3297
+#: option.c:1320 option.c:1459 option.c:3551
 #, fuzzy
 msgid "bad IPv6 address"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: option.c:1366
+#: option.c:1413
 #, fuzzy
 msgid "bad IPv4 address"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: option.c:1439 option.c:1533
+#: option.c:1486 option.c:1581
 msgid "bad domain in dhcp-option"
 msgstr "domain dalam dhcp-option salah"
 
 # OK
-#: option.c:1571
+#: option.c:1625
 msgid "dhcp-option too long"
 msgstr "dhcp-option terlalu panjang"
 
-#: option.c:1578
+#: option.c:1632
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1647
+#: option.c:1691
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1655
+#: option.c:1699
 msgid "illegal repeated keyword"
 msgstr ""
 
 # OK
-#: option.c:1726 option.c:4764
+#: option.c:1770 option.c:5080
 #, fuzzy, c-format
 msgid "cannot access directory %s: %s"
 msgstr "tidak bisa membaca %s: %s"
 
 # OK
-#: option.c:1772 tftp.c:564 dump.c:68
+#: option.c:1816 tftp.c:566 dump.c:68
 #, fuzzy, c-format
 msgid "cannot access %s: %s"
 msgstr "tidak bisa membaca %s: %s"
 
-#: option.c:1879
+#: option.c:1931
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1888
+#: option.c:1940
 msgid "bad log facility"
 msgstr ""
 
 # OK
-#: option.c:1941
+#: option.c:1993
 msgid "bad MX preference"
 msgstr "kesukaan MX salah"
 
 # OK
-#: option.c:1946
+#: option.c:1998
 msgid "bad MX name"
 msgstr "nama MX salah"
 
 # OK
-#: option.c:1960
+#: option.c:2012
 msgid "bad MX target"
 msgstr "target MX salah"
 
-#: option.c:1980
+#: option.c:2032
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1984
+#: option.c:2036
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
 # OK
-#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
+#: option.c:2291 option.c:2327
+#, fuzzy
+msgid "bad prefix length"
+msgstr "port salah"
+
+# OK
+#: option.c:2303 option.c:2348 option.c:2398
 #, fuzzy
 msgid "bad prefix"
 msgstr "port salah"
 
-#: option.c:2658
+#: option.c:2418
+msgid "prefix length too small"
+msgstr ""
+
+# OK
+#: option.c:2697
+#, fuzzy
+msgid "Bad address in --address"
+msgstr "alamat telah digunakan"
+
+# OK
+#: option.c:2751
+#, fuzzy
+msgid "bad IPv4 prefix"
+msgstr "port salah"
+
+# OK
+#: option.c:2756 option.c:3569
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "port salah"
+
+#: option.c:2777
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
+#: option.c:2843 option.c:2861
+msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+msgstr ""
+
 # OK
-#: option.c:2871
+#: option.c:3119
 #, fuzzy
 msgid "bad port range"
 msgstr "port salah"
 
-#: option.c:2897
+#: option.c:3145
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2941
+#: option.c:3189
 msgid "bad shared-network"
 msgstr ""
 
-#: option.c:2996
+#: option.c:3243
 msgid "only one tag allowed"
 msgstr ""
 
 # OK
-#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
+#: option.c:3264 option.c:3280 option.c:3406 option.c:3414 option.c:3457
 msgid "bad dhcp-range"
 msgstr "dhcp-range salah"
 
 # OK
-#: option.c:3050
+#: option.c:3298
 msgid "inconsistent DHCP range"
 msgstr "jangkauan DHCP tidak konsisten"
 
-#: option.c:3115
+#: option.c:3364
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:3117
+#: option.c:3366
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:3120
+#: option.c:3369
 msgid "prefix length must be at least 64"
 msgstr ""
 
 # OK
-#: option.c:3123
+#: option.c:3372
 #, fuzzy
 msgid "inconsistent DHCPv6 range"
 msgstr "jangkauan DHCP tidak konsisten"
 
-#: option.c:3142
+#: option.c:3391
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
 # OK
-#: option.c:3262 option.c:3340
+#: option.c:3516 option.c:3594
 #, fuzzy
 msgid "bad hex constant"
 msgstr "dhcp-host salah"
 
 # OK
-#: option.c:3315
-#, fuzzy
-msgid "bad IPv6 prefix"
-msgstr "port salah"
-
-# OK
-#: option.c:3362
+#: option.c:3617
 #, fuzzy, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "alamat IP kembar %s dalam direktif dhcp-config"
 
 # OK
-#: option.c:3422
+#: option.c:3678
 #, fuzzy
 msgid "bad DHCP host name"
 msgstr "nama MX salah"
 
 # OK
-#: option.c:3508
+#: option.c:3764
 #, fuzzy
 msgid "bad tag-if"
 msgstr "target MX salah"
 
 # OK
-#: option.c:3851 option.c:4324
+#: option.c:4107 option.c:4623
 msgid "invalid port number"
 msgstr "nomor port tidak benar"
 
 # OK
-#: option.c:3907
+#: option.c:4163
 #, fuzzy
 msgid "bad dhcp-proxy address"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: option.c:3935
+#: option.c:4204
 #, fuzzy
 msgid "Bad dhcp-relay"
 msgstr "dhcp-range salah"
 
-#: option.c:3979
+#: option.c:4248
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3989
+#: option.c:4258
 msgid "bad DUID"
 msgstr ""
 
 # OK
-#: option.c:4023
+#: option.c:4292
 #, fuzzy
 msgid "missing address in alias"
 msgstr "alamat telah digunakan"
 
 # OK
-#: option.c:4029
+#: option.c:4298
 #, fuzzy
 msgid "invalid alias range"
 msgstr "weight tidak benar"
 
-#: option.c:4081 option.c:4097
+# OK
+#: option.c:4347
+#, fuzzy
+msgid "missing address in dynamic host"
+msgstr "alamat telah digunakan"
+
+# OK
+#: option.c:4362
+#, fuzzy
+msgid "bad dynamic host"
+msgstr "tidak bisa membaca %s: %s"
+
+#: option.c:4380 option.c:4396
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:4105
+#: option.c:4404
 msgid "duplicate CNAME"
 msgstr ""
 
 # OK
-#: option.c:4132
+#: option.c:4431
 #, fuzzy
 msgid "bad PTR record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:4167
+#: option.c:4466
 #, fuzzy
 msgid "bad NAPTR record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:4203
+#: option.c:4502
 #, fuzzy
 msgid "bad RR record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:4236
+#: option.c:4535
 #, fuzzy
 msgid "bad CAA record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:4265
+#: option.c:4564
 msgid "bad TXT record"
 msgstr "rekord TXT salah"
 
 # OK
-#: option.c:4308
+#: option.c:4607
 msgid "bad SRV record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:4315
+#: option.c:4614
 msgid "bad SRV target"
 msgstr "target SRV salah"
 
 # OK
-#: option.c:4334
+#: option.c:4633
 msgid "invalid priority"
 msgstr "prioritas tidak benar"
 
 # OK
-#: option.c:4339
+#: option.c:4638
 msgid "invalid weight"
 msgstr "weight tidak benar"
 
 # OK
-#: option.c:4362
+#: option.c:4661
 #, fuzzy
 msgid "Bad host-record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:4402
+#: option.c:4700
 #, fuzzy
 msgid "Bad name in host-record"
 msgstr "kesalahan nama di %s"
 
-#: option.c:4444
+#: option.c:4742
 msgid "bad value for dnssec-check-unsigned"
 msgstr ""
 
 # OK
-#: option.c:4480
+#: option.c:4778
 #, fuzzy
 msgid "bad trust anchor"
 msgstr "port salah"
 
-#: option.c:4496
+#: option.c:4794
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4507
+#: option.c:4805
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
 # OK
-#: option.c:4567
+#: option.c:4865
 msgid "missing \""
 msgstr "kurang \""
 
 # OK
-#: option.c:4624
+#: option.c:4922
 msgid "bad option"
 msgstr "pilihan salah"
 
 # OK
-#: option.c:4626
+#: option.c:4924
 msgid "extraneous parameter"
 msgstr "parameter berlebihan"
 
 # OK
-#: option.c:4628
+#: option.c:4926
 msgid "missing parameter"
 msgstr "parameter kurang"
 
 # OK
-#: option.c:4630
+#: option.c:4928
 #, fuzzy
 msgid "illegal option"
 msgstr "pilihan salah"
 
 # OK
-#: option.c:4637
+#: option.c:4935
 msgid "error"
 msgstr "kesalahan"
 
 # OK
-#: option.c:4639
+#: option.c:4937
 #, fuzzy, c-format
 msgid " at line %d of %s"
 msgstr "%s pada baris %d dari %%s"
 
 # OK
-#: option.c:4654 option.c:4939 option.c:4950
+#: option.c:4952 option.c:5229 option.c:5240
 #, fuzzy, c-format
 msgid "read %s"
 msgstr "membaca %s"
 
 # OK
-#: option.c:4717 option.c:4840 tftp.c:754
+#: option.c:5015 option.c:5162 tftp.c:775
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "tidak bisa membaca %s: %s"
 
-#: option.c:5027
+#: option.c:5316
 msgid "junk found in command line"
 msgstr ""
 
 # OK
-#: option.c:5067
+#: option.c:5356
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Dnsmasq versi %s  %s\n"
 
 # OK
-#: option.c:5068
+#: option.c:5357
 #, fuzzy, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1325,625 +1405,664 @@ msgstr ""
 "\n"
 
 # OK
-#: option.c:5069
+#: option.c:5358
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Perangkat lunak ini tersedia TANPA JAMINAN SEDIKITPUN.\n"
 
 # OK
-#: option.c:5070
+#: option.c:5359
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsdmasq adalah perangkat lunak bebas, dan Anda dipersilahkan untuk membagikannya\n"
 
 # OK
-#: option.c:5071
+#: option.c:5360
 #, fuzzy, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "dengan aturan GNU General Public License, versi 2.\n"
 
-#: option.c:5088
+#: option.c:5377
 msgid "try --help"
 msgstr ""
 
-#: option.c:5090
+#: option.c:5379
 msgid "try -w"
 msgstr ""
 
 # OK
-#: option.c:5092
+#: option.c:5381
 #, fuzzy, c-format
 msgid "bad command line options: %s"
 msgstr "pilihan baris perintah salah: %s."
 
-#: option.c:5161
+#: option.c:5450
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
 # OK
-#: option.c:5195
+#: option.c:5491
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "tidak bisa mendapatkan host-name: %s"
 
 # OK
-#: option.c:5223
+#: option.c:5519
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "hanya satu file resolv.conf yang diperbolehkan dalam modus no-poll."
 
 # OK
-#: option.c:5233
+#: option.c:5529
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "harus mempunyai tepat satu resolv.conf untuk mendapatkan nama domain."
 
 # OK
-#: option.c:5236 network.c:1594 dhcp.c:876
+#: option.c:5532 network.c:1670 dhcp.c:880
 #, fuzzy, c-format
 msgid "failed to read %s: %s"
 msgstr "gagal membaca %s: %s"
 
 # OK
-#: option.c:5253
+#: option.c:5549
 #, c-format
 msgid "no search directive found in %s"
 msgstr "tidak ditemukan direktif search di %s"
 
-#: option.c:5274
+#: option.c:5570
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:5283
+#: option.c:5579
 msgid "syntax check OK"
 msgstr ""
 
 # OK
-#: forward.c:99
+#: forward.c:104
 #, fuzzy, c-format
 msgid "failed to send packet: %s"
 msgstr "gagal mendengarkan di socket: %s"
 
-#: forward.c:614
+#: forward.c:601
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
 # OK
-#: forward.c:677
+#: forward.c:666
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "nameserver %s menolak melakukan resolusi rekursif"
 
-#: forward.c:709
+#: forward.c:702
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:961
+#: forward.c:1074
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1370 forward.c:1830
+#: forward.c:1381 forward.c:1910
 msgid "Ignoring query from non-local network"
 msgstr ""
 
+#: forward.c:2198
+#, fuzzy, c-format
+msgid "failed to bind server socket to %s: %s"
+msgstr "gagal mem-bind socket untuk mendengarkan %s: %s"
+
 # OK
-#: forward.c:2321
+#: forward.c:2494
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
 
 # OK
-#: network.c:698
+#: forward.c:2496
+#, fuzzy, c-format
+msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
+
+#: network.c:670
+#, c-format
+msgid "stopped listening on %s(#%d): %s port %d"
+msgstr ""
+
+# OK
+#: network.c:867
 #, fuzzy, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "gagal membuat socket: %s "
 
-#: network.c:1002
+#: network.c:1148
+#, c-format
+msgid "listening on %s(#%d): %s port %d"
+msgstr ""
+
+# OK
+#: network.c:1175
+#, fuzzy, c-format
+msgid "listening on %s port %d"
+msgstr "gagal membaca %s: %s"
+
+#: network.c:1208
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1009
+#: network.c:1215
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
 # OK
-#: network.c:1018
+#: network.c:1224
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "peringatan: antarmuka %s tidak ada"
 
 # OK
-#: network.c:1027
+#: network.c:1233
 #, fuzzy, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "menggunakan alamat lokal saja untuk %s %s"
 
 # OK
-#: network.c:1085
+#: network.c:1291
 #, fuzzy, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "gagal mem-bind socket server DHCP: %s"
 
-#: network.c:1090
+#: network.c:1296
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1307
+#: network.c:1492
 #, fuzzy, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "gagal mem-bind socket untuk mendengarkan %s: %s"
 
 # OK
-#: network.c:1499
+#: network.c:1569
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "mengabaikan nameserver %s - antarmuka lokal"
 
 # OK
-#: network.c:1510
+#: network.c:1580
 #, fuzzy, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "mengabaikan nameserver %s - tak dapat membuat/mem-bind socket: %s"
 
-#: network.c:1530
+#: network.c:1598
 msgid "(no DNSSEC)"
 msgstr ""
 
 # OK
-#: network.c:1533
+#: network.c:1601
 msgid "unqualified"
 msgstr "tidak memenuhi syarat"
 
-#: network.c:1533
+#: network.c:1601
 msgid "names"
 msgstr ""
 
-#: network.c:1535
+#: network.c:1603
 msgid "default"
 msgstr ""
 
 # OK
-#: network.c:1537
+#: network.c:1605
 msgid "domain"
 msgstr "domain"
 
 # OK
-#: network.c:1543
-#, fuzzy, c-format
-msgid "using only locally-known addresses for %s %s"
-msgstr "menggunakan alamat lokal saja untuk %s %s"
-
-# OK
-#: network.c:1546
-#, fuzzy, c-format
-msgid "using standard nameservers for %s %s"
-msgstr "menggunakan nameserver %s#%d untuk %s %s"
-
-# OK
-#: network.c:1548
+#: network.c:1607
 #, fuzzy, c-format
-msgid "using nameserver %s#%d for %s %s %s"
+msgid "using nameserver %s#%d for %s %s%s %s"
 msgstr "menggunakan nameserver %s#%d untuk %s %s"
 
 # OK
-#: network.c:1552
+#: network.c:1611
 #, fuzzy, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "menggunakan nameserver %s#%d untuk %s %s"
 
 # OK
-#: network.c:1555
+#: network.c:1614
 #, fuzzy, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "menggunakan nameserver %s#%d"
 
 # OK
-#: network.c:1557
+#: network.c:1616
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "menggunakan nameserver %s#%d"
 
 # OK
-#: network.c:1562
+#: network.c:1630
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s"
+msgstr "menggunakan alamat lokal saja untuk %s %s"
+
+# OK
+#: network.c:1633
+#, fuzzy, c-format
+msgid "using standard nameservers for %s"
+msgstr "menggunakan nameserver %s#%d untuk %s %s"
+
+# OK
+#: network.c:1637
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "menggunakan nameserver %s#%d"
 
 # OK
-#: network.c:1564
+#: network.c:1639
 #, fuzzy, c-format
 msgid "using %d more nameservers"
 msgstr "menggunakan nameserver %s#%d"
 
-#: dnsmasq.c:173
+#: dnsmasq.c:184
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:188
+#: dnsmasq.c:199
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:202
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
 # OK
-#: dnsmasq.c:193
+#: dnsmasq.c:204
 #, fuzzy
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
 # OK
-#: dnsmasq.c:199
+#: dnsmasq.c:210
 #, fuzzy
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
-#: dnsmasq.c:204
+#: dnsmasq.c:217
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
 # OK
-#: dnsmasq.c:207
+#: dnsmasq.c:223
 #, fuzzy
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
-#: dnsmasq.c:212
+#: dnsmasq.c:228
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:217
+#: dnsmasq.c:233
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
 # OK
-#: dnsmasq.c:222
+#: dnsmasq.c:238
 #, fuzzy
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
 # OK
-#: dnsmasq.c:227
+#: dnsmasq.c:243
 #, fuzzy
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
 # OK
-#: dnsmasq.c:232
+#: dnsmasq.c:248
 #, fuzzy
 msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
-#: dnsmasq.c:236
+#: dnsmasq.c:259
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:243
+#: dnsmasq.c:266
 msgid "--auth-server required when an auth zone is defined."
 msgstr ""
 
-#: dnsmasq.c:248
+#: dnsmasq.c:271
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:268
+#: dnsmasq.c:291
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:332
+#: dnsmasq.c:355
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
 # OK
-#: dnsmasq.c:335
+#: dnsmasq.c:358
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "gagal mendapatkan daftar antarmuka: %s"
 
 # OK
-#: dnsmasq.c:344
+#: dnsmasq.c:367
 #, c-format
 msgid "unknown interface %s"
 msgstr "antarmuka tidak dikenal %s"
 
 # OK
-#: dnsmasq.c:406
+#: dnsmasq.c:437
 #, fuzzy
 msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
 # OK
-#: dnsmasq.c:416 dnsmasq.c:1171
+#: dnsmasq.c:445 dnsmasq.c:1207
 #, c-format
 msgid "DBus error: %s"
 msgstr "DBus error: %s"
 
 # OK
-#: dnsmasq.c:419
+#: dnsmasq.c:448
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
 # OK
-#: dnsmasq.c:429
+#: dnsmasq.c:456 dnsmasq.c:1228
+#, fuzzy, c-format
+msgid "UBus error: %s"
+msgstr "DBus error: %s"
+
+# OK
+#: dnsmasq.c:459
 #, fuzzy
 msgid "UBus not available: set HAVE_UBUS in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
-#: dnsmasq.c:459
+#: dnsmasq.c:489
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:535
+#: dnsmasq.c:565
 #, c-format
 msgid "process is missing required capability %s"
 msgstr ""
 
-#: dnsmasq.c:567
+#: dnsmasq.c:597
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
 # OK
-#: dnsmasq.c:815
+#: dnsmasq.c:845
 #, fuzzy, c-format
 msgid "started, version %s DNS disabled"
 msgstr "dimulai, cache versi %s di disable"
 
 # OK
-#: dnsmasq.c:820
+#: dnsmasq.c:850
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "dimulai, versi %s ukuran cache %d"
 
-#: dnsmasq.c:822
+#: dnsmasq.c:852
 msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
 msgstr ""
 
 # OK
-#: dnsmasq.c:825
+#: dnsmasq.c:855
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "dimulai, cache versi %s di disable"
 
-#: dnsmasq.c:828
+#: dnsmasq.c:858
 msgid "DNS service limited to local subnets"
 msgstr ""
 
 # OK
-#: dnsmasq.c:831
+#: dnsmasq.c:861
 #, c-format
 msgid "compile time options: %s"
 msgstr "pilihan-pilihan saat kompilasi: %s"
 
 # OK
-#: dnsmasq.c:840
+#: dnsmasq.c:870
 msgid "DBus support enabled: connected to system bus"
 msgstr "dukungan DBus dimungkinkan: terkoneksi pada bus sistem"
 
 # OK
-#: dnsmasq.c:842
+#: dnsmasq.c:872
 msgid "DBus support enabled: bus connection pending"
 msgstr "dukungan DBus dimungkinkan: koneksi bus ditunda"
 
 # OK
-#: dnsmasq.c:850
+#: dnsmasq.c:880
 #, fuzzy
 msgid "UBus support enabled: connected to system bus"
 msgstr "dukungan DBus dimungkinkan: terkoneksi pada bus sistem"
 
 # OK
-#: dnsmasq.c:852
+#: dnsmasq.c:882
 #, fuzzy
 msgid "UBus support enabled: bus connection pending"
 msgstr "dukungan DBus dimungkinkan: koneksi bus ditunda"
 
-#: dnsmasq.c:872
+#: dnsmasq.c:902
 msgid "DNSSEC validation enabled but all unsigned answers are trusted"
 msgstr ""
 
-#: dnsmasq.c:874
+#: dnsmasq.c:904
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:878
+#: dnsmasq.c:908
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:881
+#: dnsmasq.c:911
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:884
+#: dnsmasq.c:914
 #, c-format
 msgid "configured with trust anchor for %s keytag %u"
 msgstr ""
 
 # OK
-#: dnsmasq.c:890
+#: dnsmasq.c:920
 #, fuzzy, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "gagal memuat nama-nama dari %s: %s"
 
 # OK
-#: dnsmasq.c:894
+#: dnsmasq.c:924
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "setelan opsi --bind-interfaces disebabkan keterbatasan OS"
 
 # OK
-#: dnsmasq.c:906
+#: dnsmasq.c:936
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "peringatan: antarmuka %s tidak ada"
 
-#: dnsmasq.c:911
+#: dnsmasq.c:941
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
 # OK
-#: dnsmasq.c:914
+#: dnsmasq.c:944
 #, fuzzy
 msgid "warning: no upstream servers configured"
 msgstr "menyetel server-server di atas dengan DBus"
 
-#: dnsmasq.c:918
+#: dnsmasq.c:948
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:939
+#: dnsmasq.c:969
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:944
+#: dnsmasq.c:974
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "root is "
 msgstr ""
 
 # OK
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 #, fuzzy
 msgid "enabled"
 msgstr "di disable"
 
-#: dnsmasq.c:960
+#: dnsmasq.c:993
 msgid "secure mode"
 msgstr ""
 
 # OK
-#: dnsmasq.c:961
+#: dnsmasq.c:994
 #, fuzzy
 msgid "single port mode"
 msgstr "nomor port tidak benar"
 
-#: dnsmasq.c:964
+#: dnsmasq.c:997
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:968
+#: dnsmasq.c:1001
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:994
+#: dnsmasq.c:1027
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1173
+#: dnsmasq.c:1204
 msgid "connected to system DBus"
 msgstr "terhubung ke sistem DBus"
 
-#: dnsmasq.c:1345
+# OK
+#: dnsmasq.c:1225
+#, fuzzy
+msgid "connected to system UBus"
+msgstr "terhubung ke sistem DBus"
+
+#: dnsmasq.c:1391
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1349
+#: dnsmasq.c:1395
 #, fuzzy, c-format
 msgid "failed to create helper: %s"
 msgstr "gagal membaca %s: %s"
 
-#: dnsmasq.c:1353
+#: dnsmasq.c:1399
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1357
+#: dnsmasq.c:1403
 #, fuzzy, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "gagal memuat nama-nama dari %s: %s"
 
 # OK
-#: dnsmasq.c:1361
+#: dnsmasq.c:1407
 #, fuzzy, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "gagal memuat nama-nama dari %s: %s"
 
 # OK
-#: dnsmasq.c:1365
+#: dnsmasq.c:1411
 #, fuzzy, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "gagal membaca %s: %s"
 
 # OK
-#: dnsmasq.c:1369
+#: dnsmasq.c:1415
 #, fuzzy, c-format
 msgid "cannot open log %s: %s"
 msgstr "tidak bisa membuka %s:%s"
 
 # OK
-#: dnsmasq.c:1373
+#: dnsmasq.c:1419
 #, fuzzy, c-format
 msgid "failed to load Lua script: %s"
 msgstr "gagal memuat %S: %s"
 
-#: dnsmasq.c:1377
+#: dnsmasq.c:1423
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1381
+#: dnsmasq.c:1427
 #, fuzzy, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "tidak dapat membuka atau membuat file lease: %s"
 
-#: dnsmasq.c:1465
+#: dnsmasq.c:1511
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1469
+#: dnsmasq.c:1515
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1473
+#: dnsmasq.c:1519
 #, fuzzy, c-format
 msgid "failed to execute %s: %s"
 msgstr "gagal mengakses %s: %s"
 
-#: dnsmasq.c:1513
+#: dnsmasq.c:1559
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
+#: dnsmasq.c:1594 dnssec.c:160 dnssec.c:204
 #, fuzzy, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "gagal membaca %s: %s"
 
-#: dnsmasq.c:1560
+#: dnsmasq.c:1606
 msgid "exiting on receipt of SIGTERM"
 msgstr "keluar karena menerima SIGTERM"
 
 # OK
-#: dnsmasq.c:1588
+#: dnsmasq.c:1634
 #, fuzzy, c-format
 msgid "failed to access %s: %s"
 msgstr "gagal mengakses %s: %s"
 
 # OK
-#: dnsmasq.c:1618
+#: dnsmasq.c:1664
 #, c-format
 msgid "reading %s"
 msgstr "membaca %s"
 
 # OK
-#: dnsmasq.c:1629
+#: dnsmasq.c:1675
 #, fuzzy, c-format
 msgid "no servers found in %s, will retry"
 msgstr "tidak ditemukan direktif search di %s"
@@ -1994,29 +2113,29 @@ msgstr ""
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:471
+#: dhcp.c:473
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
 # OK
-#: dhcp.c:526
+#: dhcp.c:530
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "jangkauan DHCP %s -- %s tidak konsisten dengan netmask %s"
 
 # OK
-#: dhcp.c:914
+#: dhcp.c:918
 #, fuzzy, c-format
 msgid "bad line at %s line %d"
 msgstr "kesalahan nama pada %s baris %d"
 
-#: dhcp.c:957
+#: dhcp.c:961
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1100 rfc3315.c:2139
+#: dhcp.c:1105 rfc3315.c:2182
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
@@ -2068,7 +2187,7 @@ msgstr ""
 # OK
 #: lease.c:381
 #, fuzzy, c-format
-msgid "failed to write %s: %s (retry in %us)"
+msgid "failed to write %s: %s (retry in %u s)"
 msgstr "gagal membaca %s: %s"
 
 #: lease.c:955
@@ -2077,229 +2196,229 @@ msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
 # OK
-#: rfc2131.c:372
-#, c-format
-msgid "no address range available for DHCP request %s %s"
-msgstr "tidak ada alamat yang bisa dipakai untuk permintaan DHCP %s %s"
-
-# OK
-#: rfc2131.c:373
+#: rfc2131.c:378
 msgid "with subnet selector"
 msgstr "dengan pemilih subnet"
 
 # OK
-#: rfc2131.c:373
+#: rfc2131.c:383
 msgid "via"
 msgstr "lewat"
 
 # OK
-#: rfc2131.c:385
+#: rfc2131.c:389
+#, c-format
+msgid "no address range available for DHCP request %s %s"
+msgstr "tidak ada alamat yang bisa dipakai untuk permintaan DHCP %s %s"
+
+# OK
+#: rfc2131.c:403
 #, fuzzy, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "tidak ada alamat yang bisa dipakai untuk permintaan DHCP %s %s"
 
-#: rfc2131.c:388 rfc3315.c:319
+#: rfc2131.c:409 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
 # OK
-#: rfc2131.c:499
+#: rfc2131.c:521
 #, fuzzy, c-format
 msgid "%u vendor class: %s"
 msgstr "DBus error: %s"
 
 # OK
-#: rfc2131.c:501
+#: rfc2131.c:523
 #, fuzzy, c-format
 msgid "%u user class: %s"
 msgstr "DBus error: %s"
 
 # OK
-#: rfc2131.c:535
+#: rfc2131.c:557
 msgid "disabled"
 msgstr "di disable"
 
 # OK
-#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
-#: rfc3315.c:1097
+#: rfc2131.c:598 rfc2131.c:1087 rfc2131.c:1532 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1121
 msgid "ignored"
 msgstr "diabaikan"
 
 # OK
-#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
+#: rfc2131.c:613 rfc2131.c:1333 rfc3315.c:867
 msgid "address in use"
 msgstr "alamat telah digunakan"
 
 # OK
-#: rfc2131.c:605 rfc2131.c:1119
+#: rfc2131.c:627 rfc2131.c:1141
 msgid "no address available"
 msgstr "tak ada alamat yang tersedia"
 
 # OK
-#: rfc2131.c:612 rfc2131.c:1273
+#: rfc2131.c:634 rfc2131.c:1295
 msgid "wrong network"
 msgstr "jaringan yang salah"
 
 # OK
-#: rfc2131.c:627
+#: rfc2131.c:649
 msgid "no address configured"
 msgstr "tak ada alamat yang disetel"
 
 # OK
-#: rfc2131.c:633 rfc2131.c:1323
+#: rfc2131.c:655 rfc2131.c:1346
 msgid "no leases left"
 msgstr "tak ada lease yang tersisa"
 
-#: rfc2131.c:734 rfc3315.c:499
+#: rfc2131.c:756 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:864
+#: rfc2131.c:885
 msgid "PXE BIS not supported"
 msgstr ""
 
 # OK
-#: rfc2131.c:1032 rfc3315.c:1197
+#: rfc2131.c:1054 rfc3315.c:1222
 #, fuzzy, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "men-disable alamat statik DHCP %s"
 
 # OK
-#: rfc2131.c:1053
+#: rfc2131.c:1075
 msgid "unknown lease"
 msgstr "lease tidak diketahui"
 
-#: rfc2131.c:1088
+#: rfc2131.c:1110
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1098
+#: rfc2131.c:1120
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1101
+#: rfc2131.c:1123
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1117 rfc2131.c:1316
+#: rfc2131.c:1139 rfc2131.c:1339
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1209
+#: rfc2131.c:1231
 msgid "wrong server-ID"
 msgstr ""
 
 # OK
-#: rfc2131.c:1228
+#: rfc2131.c:1250
 msgid "wrong address"
 msgstr "alamat salah"
 
 # OK
-#: rfc2131.c:1246 rfc3315.c:961
+#: rfc2131.c:1268 rfc3315.c:975
 msgid "lease not found"
 msgstr "lease tak ditemukan"
 
 # OK
-#: rfc2131.c:1281
+#: rfc2131.c:1303
 msgid "address not available"
 msgstr "alamat tak tersedia"
 
 # OK
-#: rfc2131.c:1292
+#: rfc2131.c:1314
 msgid "static lease available"
 msgstr "lease statik tak tersedia"
 
 # OK
-#: rfc2131.c:1296
+#: rfc2131.c:1318
 msgid "address reserved"
 msgstr "alamat telah dipesan"
 
-#: rfc2131.c:1304
+#: rfc2131.c:1327
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1845
+#: rfc2131.c:1866
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
 # OK
-#: rfc2131.c:1854
+#: rfc2131.c:1875
 #, fuzzy, c-format
 msgid "%u server name: %s"
 msgstr "DBus error: %s"
 
 # OK
-#: rfc2131.c:1862
+#: rfc2131.c:1885
 #, fuzzy, c-format
 msgid "%u next server: %s"
 msgstr "DBus error: %s"
 
-#: rfc2131.c:1865
+#: rfc2131.c:1889
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1928
+#: rfc2131.c:1952
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr ""
 
-#: rfc2131.c:2219
+#: rfc2131.c:2262
 msgid "PXE menu too large"
 msgstr ""
 
 # OK
-#: rfc2131.c:2358 rfc3315.c:1470
+#: rfc2131.c:2425 rfc3315.c:1511
 #, fuzzy, c-format
 msgid "%u requested options: %s"
 msgstr "pilihan-pilihan saat kompilasi: %s"
 
-#: rfc2131.c:2675
+#: rfc2131.c:2742
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2738
+#: rfc2131.c:2805
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
 # OK
-#: netlink.c:76
+#: netlink.c:93
 #, fuzzy, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "tidak bisa mem-bind netlink socket: %s"
 
 # OK
-#: netlink.c:352
+#: netlink.c:377
 #, fuzzy, c-format
 msgid "netlink returns error: %s"
 msgstr "DBus error: %s"
 
-#: dbus.c:438
+#: dbus.c:434
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:443
+#: dbus.c:439
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
 # OK
-#: dbus.c:717
+#: dbus.c:713
 msgid "setting upstream servers from DBus"
 msgstr "menyetel server-server di atas dengan DBus"
 
 # OK
-#: dbus.c:764
+#: dbus.c:760
 msgid "could not register a DBus message handler"
 msgstr "tidak bisa mendaftar sebuah DBus message handler"
 
@@ -2329,33 +2448,38 @@ msgstr ""
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:347
+#: tftp.c:349
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:363
+#: tftp.c:365
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
 # OK
-#: tftp.c:510
+#: tftp.c:512
 #, fuzzy, c-format
 msgid "file %s not found"
 msgstr "lease tak ditemukan"
 
+#: tftp.c:602
+#, c-format
+msgid "ignoring packet from %s (TID mismatch)"
+msgstr ""
+
 # OK
-#: tftp.c:628
+#: tftp.c:646
 #, fuzzy, c-format
 msgid "failed sending %s to %s"
 msgstr "gagal membaca %s: %s"
 
-#: tftp.c:628
+#: tftp.c:646
 #, c-format
 msgid "sent %s to %s"
 msgstr ""
 
-#: tftp.c:678
+#: tftp.c:696
 #, c-format
 msgid "error %d %s received from %s"
 msgstr ""
@@ -2371,7 +2495,7 @@ msgid "log failed: %s"
 msgstr ""
 
 # OK
-#: log.c:471
+#: log.c:477
 msgid "FAILED to start up"
 msgstr "GAGAL untuk memulai"
 
@@ -2434,12 +2558,12 @@ msgstr "tidak ada antarmuka dengan alamat %s"
 msgid "address unavailable"
 msgstr "alamat tak tersedia"
 
-#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1272
 msgid "success"
 msgstr ""
 
 # OK
-#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913 rfc3315.c:1047
 #, fuzzy
 msgid "no addresses available"
 msgstr "tak ada alamat yang tersedia"
@@ -2448,123 +2572,123 @@ msgstr "tak ada alamat yang tersedia"
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
+#: rfc3315.c:979 rfc3315.c:1180 rfc3315.c:1261
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1002
+#: rfc3315.c:1016
 msgid "deprecated"
 msgstr ""
 
 # OK
-#: rfc3315.c:1007
+#: rfc3315.c:1023
 #, fuzzy
 msgid "address invalid"
 msgstr "alamat telah digunakan"
 
-#: rfc3315.c:1057 rfc3315.c:1059
+#: rfc3315.c:1081 rfc3315.c:1083
 msgid "confirm failed"
 msgstr ""
 
 # OK
-#: rfc3315.c:1074
+#: rfc3315.c:1098
 #, fuzzy
 msgid "all addresses still on link"
 msgstr "kesalahan nama pada %s baris %d"
 
-#: rfc3315.c:1165
+#: rfc3315.c:1189
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2130
+#: rfc3315.c:2173
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
-#: dhcp-common.c:145
+#: dhcp-common.c:154
 #, c-format
 msgid "Ignoring duplicate dhcp-option %d"
 msgstr ""
 
-#: dhcp-common.c:222
+#: dhcp-common.c:231
 #, c-format
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:444
+#: dhcp-common.c:451
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
 # OK
-#: dhcp-common.c:478
+#: dhcp-common.c:485
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "alamat IP kembar %s (%s) dalam direktif dhcp-config"
 
 # OK
-#: dhcp-common.c:542
+#: dhcp-common.c:549
 #, fuzzy, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "gagal menyetel SO_REUSEADDR pada socket DHCP: %s"
 
-#: dhcp-common.c:665
+#: dhcp-common.c:672
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:676
+#: dhcp-common.c:683
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:873
+#: dhcp-common.c:880
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:876
+#: dhcp-common.c:883
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:918
+#: dhcp-common.c:925
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
 # OK
-#: dhcp-common.c:920
+#: dhcp-common.c:927
 #, fuzzy, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "DHCP, lease static pada %.0s%s, waktu lease %s"
 
-#: dhcp-common.c:922
+#: dhcp-common.c:929
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
 # OK
-#: dhcp-common.c:923
+#: dhcp-common.c:930
 #, fuzzy, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "DHCP, jangkaun IP %s -- %s, waktu lease %s"
 
-#: dhcp-common.c:936
+#: dhcp-common.c:943
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
 # OK
-#: dhcp-common.c:939
+#: dhcp-common.c:946
 #, fuzzy, c-format
 msgid "router advertisement on %s%s"
 msgstr "DHCP, lease static pada %.0s%s, waktu lease %s"
 
-#: dhcp-common.c:950
+#: dhcp-common.c:957
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:952
+#: dhcp-common.c:959
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2575,34 +2699,121 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "tidak bisa membuat socket DHCP: %s"
 
-#: auth.c:439
+#: auth.c:464
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
 
 # OK
-#: ipset.c:95
-#, fuzzy, c-format
-msgid "failed to find kernel version: %s"
-msgstr "gagal mem-bind socket server DHCP: %s"
-
-# OK
-#: ipset.c:114
+#: ipset.c:99
 #, fuzzy, c-format
 msgid "failed to create IPset control socket: %s"
 msgstr "gagal membuat socket: %s "
 
 # OK
-#: ipset.c:226
+#: ipset.c:211
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "gagal membaca %s: %s"
 
+#: pattern.c:29
+#, c-format
+msgid "[pattern.c:%d] Assertion failure: %s"
+msgstr ""
+
+#: pattern.c:142
+#, c-format
+msgid "Invalid DNS name: Invalid character %c."
+msgstr ""
+
+#: pattern.c:151
+msgid "Invalid DNS name: Empty label."
+msgstr ""
+
+#: pattern.c:156
+msgid "Invalid DNS name: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:170
+msgid "Invalid DNS name: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:176
+#, c-format
+msgid "Invalid DNS name: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:184
+#, c-format
+msgid "Invalid DNS name: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:189
+msgid "Invalid DNS name: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:199
+msgid "Invalid DNS name: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:204
+#, c-format
+msgid "DNS name has invalid length (%zu)."
+msgstr ""
+
+#: pattern.c:258
+#, c-format
+msgid "Invalid DNS name pattern: Invalid character %c."
+msgstr ""
+
+#: pattern.c:267
+msgid "Invalid DNS name pattern: Empty label."
+msgstr ""
+
+#: pattern.c:272
+msgid "Invalid DNS name pattern: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:285
+msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+msgstr ""
+
+#: pattern.c:295
+msgid "Invalid DNS name pattern: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:301
+#, c-format
+msgid "Invalid DNS name pattern: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:309
+#, c-format
+msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:314
+msgid "Invalid DNS name pattern: Wildcard within final two labels."
+msgstr ""
+
+#: pattern.c:319
+msgid "Invalid DNS name pattern: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:329
+msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:334
+#, c-format
+msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
+msgstr ""
+
 #: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: dnssec.c:902
+#: dnssec.c:1014
 #, c-format
 msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
 msgstr ""
@@ -2638,7 +2849,7 @@ msgstr ""
 # OK
 #: tables.c:101
 #, fuzzy, c-format
-msgid "IPset: error:%s"
+msgid "IPset: error: %s"
 msgstr "DBus error: %s"
 
 #: tables.c:108
@@ -2708,60 +2919,57 @@ msgid "bad header in %s"
 msgstr "alamat telah digunakan"
 
 # OK
-#: dump.c:201
+#: dump.c:205
 #, fuzzy
 msgid "failed to write packet dump"
 msgstr "gagal mendengarkan di socket: %s"
 
-#: dump.c:203
+#: dump.c:207
 #, c-format
 msgid "dumping UDP packet %u mask 0x%04x"
 msgstr ""
 
-#: ubus.c:52
+#: ubus.c:79
 #, c-format
 msgid "UBus subscription callback: %s subscriber(s)"
 msgstr ""
 
 # OK
-#: ubus.c:73
+#: ubus.c:99
 #, fuzzy, c-format
 msgid "Cannot reconnect to UBus: %s"
 msgstr "tidak bisa membuka %s:%s"
 
-#: ubus.c:89
-msgid "Cannot initialize UBus: connection failed"
-msgstr ""
-
-# OK
-#: ubus.c:102
-#, fuzzy, c-format
-msgid "Cannot add object to UBus: %s"
-msgstr "tidak bisa membuka %s:%s"
-
-# OK
-#: ubus.c:112
-#, fuzzy
-msgid "Connected to system UBus"
-msgstr "terhubung ke sistem DBus"
-
-#: ubus.c:122
+#: ubus.c:135
 msgid "Cannot set UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:142
+#: ubus.c:155
 msgid "Cannot poll UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:155
+#: ubus.c:168
 msgid "Disconnecting from UBus"
 msgstr ""
 
+#: ubus.c:179 ubus.c:326
+#, c-format
+msgid "UBus command failed: %d (%s)"
+msgstr ""
+
+#: hash-questions.c:40
+msgid "Failed to create SHA-256 hash object"
+msgstr ""
+
 # OK
-#: ubus.c:199
-#, fuzzy, c-format
-msgid "Failed to send UBus event: %s"
-msgstr "gagal mendengarkan di socket: %s"
+#, fuzzy
+#~ msgid "Cannot add object to UBus: %s"
+#~ msgstr "tidak bisa membuka %s:%s"
+
+# OK
+#, fuzzy
+#~ msgid "Failed to send UBus event: %s"
+#~ msgstr "gagal mendengarkan di socket: %s"
 
 # OK
 #~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
index 4d29751..6ed0010 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -16,1650 +16,1753 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: cache.c:559
+#: cache.c:572
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:1081
+#: cache.c:1094
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr ""
 
-#: cache.c:1103 dhcp.c:927
+#: cache.c:1116 dhcp.c:931
 #, c-format
 msgid "bad address at %s line %d"
 msgstr ""
 
-#: cache.c:1156 dhcp.c:943
+#: cache.c:1169 dhcp.c:947
 #, c-format
 msgid "bad name at %s line %d"
 msgstr ""
 
-#: cache.c:1167 dhcp.c:1018
+#: cache.c:1180 dhcp.c:1022
 #, c-format
 msgid "read %s - %d addresses"
 msgstr ""
 
-#: cache.c:1283
+#: cache.c:1296
 msgid "cleared cache"
 msgstr ""
 
-#: cache.c:1345
+#: cache.c:1358
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1391
+#: cache.c:1404
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
-#: cache.c:1415
+#: cache.c:1428
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr ""
 
-#: cache.c:1663
+#: cache.c:1674
 #, c-format
 msgid "time %lu"
 msgstr ""
 
-#: cache.c:1664
+#: cache.c:1675
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr ""
 
-#: cache.c:1666
+#: cache.c:1677
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1669
+#: cache.c:1680
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1694
+#: cache.c:1702
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
 
-#: util.c:47
+#: util.c:51
 #, c-format
 msgid "failed to seed the random number generator: %s"
 msgstr ""
 
-#: util.c:224
+#: util.c:228
 msgid "failed to allocate memory"
 msgstr ""
 
-#: util.c:281 option.c:641
+#: util.c:285 option.c:665
 msgid "could not get memory"
 msgstr ""
 
-#: util.c:302
+#: util.c:306
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr ""
 
-#: util.c:310
+#: util.c:314
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr ""
 
-#: util.c:506
+#: util.c:520
 #, c-format
 msgid "infinite"
 msgstr ""
 
-#: option.c:358
+#: util.c:808
+#, c-format
+msgid "failed to find kernel version: %s"
+msgstr ""
+
+#: option.c:372
 msgid "Specify local address(es) to listen on."
 msgstr ""
 
-#: option.c:359
+#: option.c:373
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr ""
 
-#: option.c:360
+#: option.c:374
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr ""
 
-#: option.c:361
+#: option.c:375
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr ""
 
-#: option.c:362
+#: option.c:376
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr ""
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr ""
 
-#: option.c:364
+#: option.c:378
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr ""
 
-#: option.c:365
+#: option.c:379
 msgid "Do NOT forward queries with no domain part."
 msgstr ""
 
-#: option.c:366
+#: option.c:380
 msgid "Return self-pointing MX records for local hosts."
 msgstr ""
 
-#: option.c:367
+#: option.c:381
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr ""
 
-#: option.c:368
+#: option.c:382
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr ""
 
-#: option.c:369
+#: option.c:383
 msgid "Enable DHCP in the range given with lease duration."
 msgstr ""
 
-#: option.c:370
+#: option.c:384
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr ""
 
-#: option.c:371
+#: option.c:385
 msgid "Set address or hostname for a specified machine."
 msgstr ""
 
-#: option.c:372
+#: option.c:386
 msgid "Read DHCP host specs from file."
 msgstr ""
 
-#: option.c:373
+#: option.c:387
 msgid "Read DHCP option specs from file."
 msgstr ""
 
-#: option.c:374
+#: option.c:388
 msgid "Read DHCP host specs from a directory."
 msgstr ""
 
-#: option.c:375
+#: option.c:389
 msgid "Read DHCP options from a directory."
 msgstr ""
 
-#: option.c:376
+#: option.c:390
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
-#: option.c:377
+#: option.c:391
 #, c-format
 msgid "Do NOT load %s file."
 msgstr ""
 
-#: option.c:378
+#: option.c:392
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr ""
 
-#: option.c:379
+#: option.c:393
 msgid "Read hosts files from a directory."
 msgstr ""
 
-#: option.c:380
+#: option.c:394
 msgid "Specify interface(s) to listen on."
 msgstr ""
 
-#: option.c:381
+#: option.c:395
 msgid "Specify interface(s) NOT to listen on."
 msgstr ""
 
-#: option.c:382
+#: option.c:396
 msgid "Map DHCP user class to tag."
 msgstr ""
 
-#: option.c:383
+#: option.c:397
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:384
+#: option.c:398
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
-#: option.c:386
+#: option.c:400
+msgid "Specify vendor class to match for PXE requests."
+msgstr ""
+
+#: option.c:401
 msgid "Don't do DHCP for hosts with tag set."
 msgstr ""
 
-#: option.c:387
+#: option.c:402
 msgid "Force broadcast replies for hosts with tag set."
 msgstr ""
 
-#: option.c:388
+#: option.c:403
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr ""
 
-#: option.c:389
+#: option.c:404
 msgid "Assume we are the only DHCP server on the local network."
 msgstr ""
 
-#: option.c:390
+#: option.c:405
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:391
+#: option.c:406
 msgid "Return MX records for local hosts."
 msgstr ""
 
-#: option.c:392
+#: option.c:407
 msgid "Specify an MX record."
 msgstr ""
 
-#: option.c:393
+#: option.c:408
 msgid "Specify BOOTP options to DHCP server."
 msgstr ""
 
-#: option.c:394
+#: option.c:409
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr ""
 
-#: option.c:395
+#: option.c:410
 msgid "Do NOT cache failed search results."
 msgstr ""
 
-#: option.c:396
+#: option.c:411
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr ""
 
-#: option.c:397
+#: option.c:412
 msgid "Specify options to be sent to DHCP clients."
 msgstr ""
 
-#: option.c:398
+#: option.c:413
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
-#: option.c:399
+#: option.c:414
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr ""
 
-#: option.c:400
+#: option.c:415
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr ""
 
-#: option.c:401
+#: option.c:416
 msgid "Log DNS queries."
 msgstr ""
 
-#: option.c:402
+#: option.c:417
 msgid "Force the originating port for upstream DNS queries."
 msgstr ""
 
-#: option.c:403
+#: option.c:418
 msgid "Do NOT read resolv.conf."
 msgstr ""
 
-#: option.c:404
+#: option.c:419
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr ""
 
-#: option.c:405
+#: option.c:420
 msgid "Specify path to file with server= options"
 msgstr ""
 
-#: option.c:406
+#: option.c:421
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr ""
 
-#: option.c:407
+#: option.c:422
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr ""
 
-#: option.c:408
+#: option.c:423
 msgid "Never forward queries to specified domains."
 msgstr ""
 
-#: option.c:409
+#: option.c:424
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr ""
 
-#: option.c:410
+#: option.c:425
 msgid "Specify default target in an MX record."
 msgstr ""
 
-#: option.c:411
+#: option.c:426
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr ""
 
-#: option.c:412
+#: option.c:427
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr ""
 
-#: option.c:413
+#: option.c:428
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr ""
 
-#: option.c:414
+#: option.c:429
 msgid "Specify time-to-live ceiling for cache."
 msgstr ""
 
-#: option.c:415
+#: option.c:430
 msgid "Specify time-to-live floor for cache."
 msgstr ""
 
-#: option.c:416
+#: option.c:431
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr ""
 
-#: option.c:417
+#: option.c:432
 msgid "Map DHCP vendor class to tag."
 msgstr ""
 
-#: option.c:418
+#: option.c:433
 msgid "Display dnsmasq version and copyright information."
 msgstr ""
 
-#: option.c:419
+#: option.c:434
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr ""
 
-#: option.c:420
+#: option.c:435
 msgid "Specify a SRV record."
 msgstr ""
 
-#: option.c:421
+#: option.c:436
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
-#: option.c:422
+#: option.c:437
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr ""
 
-#: option.c:423
+#: option.c:438
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:424
+#: option.c:439
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr ""
 
-#: option.c:425
+#: option.c:440
 msgid "Specify TXT DNS record."
 msgstr ""
 
-#: option.c:426
+#: option.c:441
 msgid "Specify PTR DNS record."
 msgstr ""
 
-#: option.c:427
+#: option.c:442
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
-#: option.c:428
+#: option.c:443
 msgid "Bind only to interfaces in use."
 msgstr ""
 
-#: option.c:429
+#: option.c:444
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr ""
 
-#: option.c:430
+#: option.c:445
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr ""
 
-#: option.c:431
+#: option.c:446
 msgid "Enable the UBus interface."
 msgstr ""
 
-#: option.c:432
+#: option.c:447
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr ""
 
-#: option.c:433
+#: option.c:448
 msgid "Enable dynamic address allocation for bootp."
 msgstr ""
 
-#: option.c:434
+#: option.c:449
 msgid "Map MAC address (with wildcards) to option set."
 msgstr ""
 
-#: option.c:435
+#: option.c:450
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:436
+#: option.c:451
 msgid "Specify extra networks sharing a broadcast domain for DHCP"
 msgstr ""
 
-#: option.c:437
+#: option.c:452
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:438
+#: option.c:453
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:439
+#: option.c:454
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:440
+#: option.c:455
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:441
+#: option.c:456
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:442
+#: option.c:457
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
-#: option.c:443
+#: option.c:458
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr ""
 
-#: option.c:444
+#: option.c:459
 msgid "Do not use leasefile."
 msgstr ""
 
-#: option.c:445
+#: option.c:460
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr ""
 
-#: option.c:446
+#: option.c:461
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:447
+#: option.c:462
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:448
+#: option.c:463
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:449
+#: option.c:464
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:450
+#: option.c:465
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:451
+#: option.c:466
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:452
+#: option.c:467
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:453
+#: option.c:468
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:454
+#: option.c:469
 #, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr ""
 
-#: option.c:455
+#: option.c:470
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr ""
 
-#: option.c:456
+#: option.c:471
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:457
+#: option.c:472
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:458
+#: option.c:473
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:459
+#: option.c:474
 msgid "Use only one port for TFTP server."
 msgstr ""
 
-#: option.c:460
+#: option.c:475
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:461
+#: option.c:476
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:462
+#: option.c:477
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:463
+#: option.c:478
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:464
+#: option.c:479
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:465
+#: option.c:480
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:466
+#: option.c:481
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:467
+#: option.c:482
 msgid "Set tag if client provides given name."
 msgstr ""
 
-#: option.c:468
+#: option.c:483
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
-#: option.c:469
+#: option.c:484
 msgid "Specify NAPTR DNS record."
 msgstr ""
 
-#: option.c:470
+#: option.c:485
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:471
+#: option.c:486
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:472
+#: option.c:487
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:473
+#: option.c:488
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:474
+#: option.c:489
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:475
+#: option.c:490
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:476
+#: option.c:491
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
-#: option.c:477
+#: option.c:492
 msgid "Prompt to send to PXE clients."
 msgstr ""
 
-#: option.c:478
+#: option.c:493
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:479
+#: option.c:494
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:480
+#: option.c:495
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:481
+#: option.c:496
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
-#: option.c:482
+#: option.c:497
 msgid "Add client identification to forwarded DNS queries."
 msgstr ""
 
-#: option.c:483
+#: option.c:498
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr ""
 
-#: option.c:484
+#: option.c:499
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:485
+#: option.c:500
 msgid "Ignore client identifier option sent by DHCP clients."
 msgstr ""
 
-#: option.c:486
+#: option.c:501
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:487
+#: option.c:502
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:488
+#: option.c:503
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:489
+#: option.c:504
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:490
+#: option.c:505
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr ""
 
-#: option.c:491
+#: option.c:506
+msgid "Specify host record in interface subnet"
+msgstr ""
+
+#: option.c:507
 msgid "Specify certification authority authorization record"
 msgstr ""
 
-#: option.c:492
+#: option.c:508
 msgid "Specify arbitrary DNS resource record"
 msgstr ""
 
-#: option.c:493
+#: option.c:509
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr ""
 
-#: option.c:494
+#: option.c:510
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:495
+#: option.c:511
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:496
+#: option.c:512
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:497
+#: option.c:513
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:498
+#: option.c:514
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:499
+#: option.c:515
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:500
+#: option.c:516
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:501
+#: option.c:517
+msgid "Enable filtering of DNS queries with connection-track marks."
+msgstr ""
+
+#: option.c:518
+msgid "Set allowed DNS patterns for a connection-track mark."
+msgstr ""
+
+#: option.c:519
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:502
+#: option.c:520
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:503
+#: option.c:521
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:504
+#: option.c:522
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:505
+#: option.c:523
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:506
+#: option.c:524
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:507
+#: option.c:525
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:508
+#: option.c:526
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:509
+#: option.c:527
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:510
+#: option.c:528
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:511
+#: option.c:529
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:512
+#: option.c:530
+msgid "Log debugging information."
+msgstr ""
+
+#: option.c:531
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:513
+#: option.c:532
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:514
+#: option.c:533
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:515
+#: option.c:534
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:516
+#: option.c:535
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:517
+#: option.c:536
 msgid "Enables DHCPv4 Rapid Commit option."
 msgstr ""
 
-#: option.c:518
+#: option.c:537
 msgid "Path to debug packet dump file"
 msgstr ""
 
-#: option.c:519
+#: option.c:538
 msgid "Mask which packets to dump"
 msgstr ""
 
-#: option.c:520
+#: option.c:539
 msgid "Call dhcp-script when lease expiry changes."
 msgstr ""
 
-#: option.c:725
+#: option.c:540
+msgid "Send Cisco Umbrella identifiers including remote IP."
+msgstr ""
+
+#: option.c:541
+msgid "Do not log routine TFTP."
+msgstr ""
+
+#: option.c:771
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
 "\n"
 msgstr ""
 
-#: option.c:727
+#: option.c:773
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr ""
 
-#: option.c:729
+#: option.c:775
 #, c-format
 msgid "Valid options are:\n"
 msgstr ""
 
-#: option.c:776 option.c:884
+#: option.c:822 option.c:933
 msgid "bad address"
 msgstr ""
 
-#: option.c:799 option.c:803
+#: option.c:847 option.c:851
 msgid "bad port"
 msgstr ""
 
-#: option.c:815 option.c:844 option.c:878
+#: option.c:864 option.c:893 option.c:927
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:839 option.c:873
+#: option.c:888 option.c:922
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:852 option.c:4042
+#: option.c:901 option.c:4362
 msgid "bad interface name"
 msgstr ""
 
-#: option.c:1184
+#: option.c:1192
+msgid "inappropriate vendor:"
+msgstr ""
+
+#: option.c:1199
+msgid "inappropriate encap:"
+msgstr ""
+
+#: option.c:1225
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
-#: option.c:1198
+#: option.c:1239
 msgid "bad dhcp-option"
 msgstr ""
 
-#: option.c:1270
+#: option.c:1317
 msgid "bad IP address"
 msgstr ""
 
-#: option.c:1273 option.c:1412 option.c:3297
+#: option.c:1320 option.c:1459 option.c:3551
 msgid "bad IPv6 address"
 msgstr ""
 
-#: option.c:1366
+#: option.c:1413
 msgid "bad IPv4 address"
 msgstr ""
 
-#: option.c:1439 option.c:1533
+#: option.c:1486 option.c:1581
 msgid "bad domain in dhcp-option"
 msgstr ""
 
-#: option.c:1571
+#: option.c:1625
 msgid "dhcp-option too long"
 msgstr ""
 
-#: option.c:1578
+#: option.c:1632
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1647
+#: option.c:1691
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1655
+#: option.c:1699
 msgid "illegal repeated keyword"
 msgstr ""
 
-#: option.c:1726 option.c:4764
+#: option.c:1770 option.c:5080
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr ""
 
-#: option.c:1772 tftp.c:564 dump.c:68
+#: option.c:1816 tftp.c:566 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr ""
 
-#: option.c:1879
+#: option.c:1931
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1888
+#: option.c:1940
 msgid "bad log facility"
 msgstr ""
 
-#: option.c:1941
+#: option.c:1993
 msgid "bad MX preference"
 msgstr ""
 
-#: option.c:1946
+#: option.c:1998
 msgid "bad MX name"
 msgstr ""
 
-#: option.c:1960
+#: option.c:2012
 msgid "bad MX target"
 msgstr ""
 
-#: option.c:1980
+#: option.c:2032
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1984
+#: option.c:2036
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
-#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
+#: option.c:2291 option.c:2327
+msgid "bad prefix length"
+msgstr ""
+
+#: option.c:2303 option.c:2348 option.c:2398
 msgid "bad prefix"
 msgstr ""
 
-#: option.c:2658
+#: option.c:2418
+msgid "prefix length too small"
+msgstr ""
+
+#: option.c:2697
+msgid "Bad address in --address"
+msgstr ""
+
+#: option.c:2751
+msgid "bad IPv4 prefix"
+msgstr ""
+
+#: option.c:2756 option.c:3569
+msgid "bad IPv6 prefix"
+msgstr ""
+
+#: option.c:2777
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
-#: option.c:2871
+#: option.c:2843 option.c:2861
+msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+msgstr ""
+
+#: option.c:3119
 msgid "bad port range"
 msgstr ""
 
-#: option.c:2897
+#: option.c:3145
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2941
+#: option.c:3189
 msgid "bad shared-network"
 msgstr ""
 
-#: option.c:2996
+#: option.c:3243
 msgid "only one tag allowed"
 msgstr ""
 
-#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
+#: option.c:3264 option.c:3280 option.c:3406 option.c:3414 option.c:3457
 msgid "bad dhcp-range"
 msgstr ""
 
-#: option.c:3050
+#: option.c:3298
 msgid "inconsistent DHCP range"
 msgstr ""
 
-#: option.c:3115
+#: option.c:3364
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:3117
+#: option.c:3366
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:3120
+#: option.c:3369
 msgid "prefix length must be at least 64"
 msgstr ""
 
-#: option.c:3123
+#: option.c:3372
 msgid "inconsistent DHCPv6 range"
 msgstr ""
 
-#: option.c:3142
+#: option.c:3391
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
-#: option.c:3262 option.c:3340
+#: option.c:3516 option.c:3594
 msgid "bad hex constant"
 msgstr ""
 
-#: option.c:3315
-msgid "bad IPv6 prefix"
-msgstr ""
-
-#: option.c:3362
+#: option.c:3617
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr ""
 
-#: option.c:3422
+#: option.c:3678
 msgid "bad DHCP host name"
 msgstr ""
 
-#: option.c:3508
+#: option.c:3764
 msgid "bad tag-if"
 msgstr ""
 
-#: option.c:3851 option.c:4324
+#: option.c:4107 option.c:4623
 msgid "invalid port number"
 msgstr ""
 
-#: option.c:3907
+#: option.c:4163
 msgid "bad dhcp-proxy address"
 msgstr ""
 
-#: option.c:3935
+#: option.c:4204
 msgid "Bad dhcp-relay"
 msgstr ""
 
-#: option.c:3979
+#: option.c:4248
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3989
+#: option.c:4258
 msgid "bad DUID"
 msgstr ""
 
-#: option.c:4023
+#: option.c:4292
 msgid "missing address in alias"
 msgstr ""
 
-#: option.c:4029
+#: option.c:4298
 msgid "invalid alias range"
 msgstr ""
 
-#: option.c:4081 option.c:4097
+#: option.c:4347
+msgid "missing address in dynamic host"
+msgstr ""
+
+#: option.c:4362
+msgid "bad dynamic host"
+msgstr ""
+
+#: option.c:4380 option.c:4396
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:4105
+#: option.c:4404
 msgid "duplicate CNAME"
 msgstr ""
 
-#: option.c:4132
+#: option.c:4431
 msgid "bad PTR record"
 msgstr ""
 
-#: option.c:4167
+#: option.c:4466
 msgid "bad NAPTR record"
 msgstr ""
 
-#: option.c:4203
+#: option.c:4502
 msgid "bad RR record"
 msgstr ""
 
-#: option.c:4236
+#: option.c:4535
 msgid "bad CAA record"
 msgstr ""
 
-#: option.c:4265
+#: option.c:4564
 msgid "bad TXT record"
 msgstr ""
 
-#: option.c:4308
+#: option.c:4607
 msgid "bad SRV record"
 msgstr ""
 
-#: option.c:4315
+#: option.c:4614
 msgid "bad SRV target"
 msgstr ""
 
-#: option.c:4334
+#: option.c:4633
 msgid "invalid priority"
 msgstr ""
 
-#: option.c:4339
+#: option.c:4638
 msgid "invalid weight"
 msgstr ""
 
-#: option.c:4362
+#: option.c:4661
 msgid "Bad host-record"
 msgstr ""
 
-#: option.c:4402
+#: option.c:4700
 msgid "Bad name in host-record"
 msgstr ""
 
-#: option.c:4444
+#: option.c:4742
 msgid "bad value for dnssec-check-unsigned"
 msgstr ""
 
-#: option.c:4480
+#: option.c:4778
 msgid "bad trust anchor"
 msgstr ""
 
-#: option.c:4496
+#: option.c:4794
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4507
+#: option.c:4805
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
-#: option.c:4567
+#: option.c:4865
 msgid "missing \""
 msgstr ""
 
-#: option.c:4624
+#: option.c:4922
 msgid "bad option"
 msgstr ""
 
-#: option.c:4626
+#: option.c:4924
 msgid "extraneous parameter"
 msgstr ""
 
-#: option.c:4628
+#: option.c:4926
 msgid "missing parameter"
 msgstr ""
 
-#: option.c:4630
+#: option.c:4928
 msgid "illegal option"
 msgstr ""
 
-#: option.c:4637
+#: option.c:4935
 msgid "error"
 msgstr ""
 
-#: option.c:4639
+#: option.c:4937
 #, c-format
 msgid " at line %d of %s"
 msgstr ""
 
-#: option.c:4654 option.c:4939 option.c:4950
+#: option.c:4952 option.c:5229 option.c:5240
 #, c-format
 msgid "read %s"
 msgstr ""
 
-#: option.c:4717 option.c:4840 tftp.c:754
+#: option.c:5015 option.c:5162 tftp.c:775
 #, c-format
 msgid "cannot read %s: %s"
 msgstr ""
 
-#: option.c:5027
+#: option.c:5316
 msgid "junk found in command line"
 msgstr ""
 
-#: option.c:5067
+#: option.c:5356
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr ""
 
-#: option.c:5068
+#: option.c:5357
 #, c-format
 msgid ""
 "Compile time options: %s\n"
 "\n"
 msgstr ""
 
-#: option.c:5069
+#: option.c:5358
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr ""
 
-#: option.c:5070
+#: option.c:5359
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr ""
 
-#: option.c:5071
+#: option.c:5360
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr ""
 
-#: option.c:5088
+#: option.c:5377
 msgid "try --help"
 msgstr ""
 
-#: option.c:5090
+#: option.c:5379
 msgid "try -w"
 msgstr ""
 
-#: option.c:5092
+#: option.c:5381
 #, c-format
 msgid "bad command line options: %s"
 msgstr ""
 
-#: option.c:5161
+#: option.c:5450
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:5195
+#: option.c:5491
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr ""
 
-#: option.c:5223
+#: option.c:5519
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr ""
 
-#: option.c:5233
+#: option.c:5529
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr ""
 
-#: option.c:5236 network.c:1594 dhcp.c:876
+#: option.c:5532 network.c:1670 dhcp.c:880
 #, c-format
 msgid "failed to read %s: %s"
 msgstr ""
 
-#: option.c:5253
+#: option.c:5549
 #, c-format
 msgid "no search directive found in %s"
 msgstr ""
 
-#: option.c:5274
+#: option.c:5570
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:5283
+#: option.c:5579
 msgid "syntax check OK"
 msgstr ""
 
-#: forward.c:99
+#: forward.c:104
 #, c-format
 msgid "failed to send packet: %s"
 msgstr ""
 
-#: forward.c:614
+#: forward.c:601
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:677
+#: forward.c:666
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr ""
 
-#: forward.c:709
+#: forward.c:702
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:961
+#: forward.c:1074
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1370 forward.c:1830
+#: forward.c:1381 forward.c:1910
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2321
+#: forward.c:2198
+#, c-format
+msgid "failed to bind server socket to %s: %s"
+msgstr ""
+
+#: forward.c:2494
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr ""
 
-#: network.c:698
+#: forward.c:2496
+#, c-format
+msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+msgstr ""
+
+#: network.c:670
+#, c-format
+msgid "stopped listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:867
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr ""
 
-#: network.c:1002
+#: network.c:1148
+#, c-format
+msgid "listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:1175
+#, c-format
+msgid "listening on %s port %d"
+msgstr ""
+
+#: network.c:1208
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1009
+#: network.c:1215
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1018
+#: network.c:1224
 #, c-format
 msgid "warning: using interface %s instead"
 msgstr ""
 
-#: network.c:1027
+#: network.c:1233
 #, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr ""
 
-#: network.c:1085
+#: network.c:1291
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr ""
 
-#: network.c:1090
+#: network.c:1296
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1307
+#: network.c:1492
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr ""
 
-#: network.c:1499
+#: network.c:1569
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr ""
 
-#: network.c:1510
+#: network.c:1580
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr ""
 
-#: network.c:1530
+#: network.c:1598
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1533
+#: network.c:1601
 msgid "unqualified"
 msgstr ""
 
-#: network.c:1533
+#: network.c:1601
 msgid "names"
 msgstr ""
 
-#: network.c:1535
+#: network.c:1603
 msgid "default"
 msgstr ""
 
-#: network.c:1537
+#: network.c:1605
 msgid "domain"
 msgstr ""
 
-#: network.c:1543
+#: network.c:1607
 #, c-format
-msgid "using only locally-known addresses for %s %s"
+msgid "using nameserver %s#%d for %s %s%s %s"
 msgstr ""
 
-#: network.c:1546
+#: network.c:1611
 #, c-format
-msgid "using standard nameservers for %s %s"
+msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr ""
 
-#: network.c:1548
+#: network.c:1614
 #, c-format
-msgid "using nameserver %s#%d for %s %s %s"
+msgid "using nameserver %s#%d(via %s)"
 msgstr ""
 
-#: network.c:1552
+#: network.c:1616
 #, c-format
-msgid "NOT using nameserver %s#%d - query loop detected"
+msgid "using nameserver %s#%d"
 msgstr ""
 
-#: network.c:1555
+#: network.c:1630
 #, c-format
-msgid "using nameserver %s#%d(via %s)"
+msgid "using only locally-known addresses for %s"
 msgstr ""
 
-#: network.c:1557
+#: network.c:1633
 #, c-format
-msgid "using nameserver %s#%d"
+msgid "using standard nameservers for %s"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1637
 #, c-format
 msgid "using %d more local addresses"
 msgstr ""
 
-#: network.c:1564
+#: network.c:1639
 #, c-format
 msgid "using %d more nameservers"
 msgstr ""
 
-#: dnsmasq.c:173
+#: dnsmasq.c:184
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:188
+#: dnsmasq.c:199
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:202
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:193
+#: dnsmasq.c:204
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:199
+#: dnsmasq.c:210
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:204
+#: dnsmasq.c:217
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
-#: dnsmasq.c:207
+#: dnsmasq.c:223
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:212
+#: dnsmasq.c:228
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:217
+#: dnsmasq.c:233
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
-#: dnsmasq.c:222
+#: dnsmasq.c:238
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:227
+#: dnsmasq.c:243
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:232
+#: dnsmasq.c:248
 msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:236
+#: dnsmasq.c:259
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:243
+#: dnsmasq.c:266
 msgid "--auth-server required when an auth zone is defined."
 msgstr ""
 
-#: dnsmasq.c:248
+#: dnsmasq.c:271
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:268
+#: dnsmasq.c:291
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:332
+#: dnsmasq.c:355
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
-#: dnsmasq.c:335
+#: dnsmasq.c:358
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr ""
 
-#: dnsmasq.c:344
+#: dnsmasq.c:367
 #, c-format
 msgid "unknown interface %s"
 msgstr ""
 
-#: dnsmasq.c:406
+#: dnsmasq.c:437
 msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:416 dnsmasq.c:1171
+#: dnsmasq.c:445 dnsmasq.c:1207
 #, c-format
 msgid "DBus error: %s"
 msgstr ""
 
-#: dnsmasq.c:419
+#: dnsmasq.c:448
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:429
-msgid "UBus not available: set HAVE_UBUS in src/config.h"
+#: dnsmasq.c:456 dnsmasq.c:1228
+#, c-format
+msgid "UBus error: %s"
 msgstr ""
 
 #: dnsmasq.c:459
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr ""
+
+#: dnsmasq.c:489
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:535
+#: dnsmasq.c:565
 #, c-format
 msgid "process is missing required capability %s"
 msgstr ""
 
-#: dnsmasq.c:567
+#: dnsmasq.c:597
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
-#: dnsmasq.c:815
+#: dnsmasq.c:845
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr ""
 
-#: dnsmasq.c:820
+#: dnsmasq.c:850
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr ""
 
-#: dnsmasq.c:822
+#: dnsmasq.c:852
 msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
 msgstr ""
 
-#: dnsmasq.c:825
+#: dnsmasq.c:855
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr ""
 
-#: dnsmasq.c:828
+#: dnsmasq.c:858
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:831
+#: dnsmasq.c:861
 #, c-format
 msgid "compile time options: %s"
 msgstr ""
 
-#: dnsmasq.c:840
+#: dnsmasq.c:870
 msgid "DBus support enabled: connected to system bus"
 msgstr ""
 
-#: dnsmasq.c:842
+#: dnsmasq.c:872
 msgid "DBus support enabled: bus connection pending"
 msgstr ""
 
-#: dnsmasq.c:850
+#: dnsmasq.c:880
 msgid "UBus support enabled: connected to system bus"
 msgstr ""
 
-#: dnsmasq.c:852
+#: dnsmasq.c:882
 msgid "UBus support enabled: bus connection pending"
 msgstr ""
 
-#: dnsmasq.c:872
+#: dnsmasq.c:902
 msgid "DNSSEC validation enabled but all unsigned answers are trusted"
 msgstr ""
 
-#: dnsmasq.c:874
+#: dnsmasq.c:904
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:878
+#: dnsmasq.c:908
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:881
+#: dnsmasq.c:911
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:884
+#: dnsmasq.c:914
 #, c-format
 msgid "configured with trust anchor for %s keytag %u"
 msgstr ""
 
-#: dnsmasq.c:890
+#: dnsmasq.c:920
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr ""
 
-#: dnsmasq.c:894
+#: dnsmasq.c:924
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr ""
 
-#: dnsmasq.c:906
+#: dnsmasq.c:936
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr ""
 
-#: dnsmasq.c:911
+#: dnsmasq.c:941
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
-#: dnsmasq.c:914
+#: dnsmasq.c:944
 msgid "warning: no upstream servers configured"
 msgstr ""
 
-#: dnsmasq.c:918
+#: dnsmasq.c:948
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:939
+#: dnsmasq.c:969
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:944
+#: dnsmasq.c:974
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "root is "
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "enabled"
 msgstr ""
 
-#: dnsmasq.c:960
+#: dnsmasq.c:993
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:961
+#: dnsmasq.c:994
 msgid "single port mode"
 msgstr ""
 
-#: dnsmasq.c:964
+#: dnsmasq.c:997
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:968
+#: dnsmasq.c:1001
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:994
+#: dnsmasq.c:1027
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
-#: dnsmasq.c:1173
+#: dnsmasq.c:1204
 msgid "connected to system DBus"
 msgstr ""
 
-#: dnsmasq.c:1345
+#: dnsmasq.c:1225
+msgid "connected to system UBus"
+msgstr ""
+
+#: dnsmasq.c:1391
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
-#: dnsmasq.c:1349
+#: dnsmasq.c:1395
 #, c-format
 msgid "failed to create helper: %s"
 msgstr ""
 
-#: dnsmasq.c:1353
+#: dnsmasq.c:1399
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
-#: dnsmasq.c:1357
+#: dnsmasq.c:1403
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1361
+#: dnsmasq.c:1407
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1365
+#: dnsmasq.c:1411
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1369
+#: dnsmasq.c:1415
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1373
+#: dnsmasq.c:1419
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr ""
 
-#: dnsmasq.c:1377
+#: dnsmasq.c:1423
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
-#: dnsmasq.c:1381
+#: dnsmasq.c:1427
 #, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1465
+#: dnsmasq.c:1511
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1469
+#: dnsmasq.c:1515
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
-#: dnsmasq.c:1473
+#: dnsmasq.c:1519
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1513
+#: dnsmasq.c:1559
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
+#: dnsmasq.c:1594 dnssec.c:160 dnssec.c:204
 #, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1560
+#: dnsmasq.c:1606
 msgid "exiting on receipt of SIGTERM"
 msgstr ""
 
-#: dnsmasq.c:1588
+#: dnsmasq.c:1634
 #, c-format
 msgid "failed to access %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1618
+#: dnsmasq.c:1664
 #, c-format
 msgid "reading %s"
 msgstr ""
 
-#: dnsmasq.c:1629
+#: dnsmasq.c:1675
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr ""
@@ -1704,27 +1807,27 @@ msgstr ""
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:471
+#: dhcp.c:473
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:526
+#: dhcp.c:530
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr ""
 
-#: dhcp.c:914
+#: dhcp.c:918
 #, c-format
 msgid "bad line at %s line %d"
 msgstr ""
 
-#: dhcp.c:957
+#: dhcp.c:961
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1100 rfc3315.c:2139
+#: dhcp.c:1105 rfc3315.c:2182
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
@@ -1769,7 +1872,7 @@ msgstr ""
 
 #: lease.c:381
 #, c-format
-msgid "failed to write %s: %s (retry in %us)"
+msgid "failed to write %s: %s (retry in %u s)"
 msgstr ""
 
 #: lease.c:955
@@ -1777,203 +1880,203 @@ msgstr ""
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
-#: rfc2131.c:372
-#, c-format
-msgid "no address range available for DHCP request %s %s"
-msgstr ""
-
-#: rfc2131.c:373
+#: rfc2131.c:378
 msgid "with subnet selector"
 msgstr ""
 
-#: rfc2131.c:373
+#: rfc2131.c:383
 msgid "via"
 msgstr ""
 
-#: rfc2131.c:385
+#: rfc2131.c:389
+#, c-format
+msgid "no address range available for DHCP request %s %s"
+msgstr ""
+
+#: rfc2131.c:403
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr ""
 
-#: rfc2131.c:388 rfc3315.c:319
+#: rfc2131.c:409 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
-#: rfc2131.c:499
+#: rfc2131.c:521
 #, c-format
 msgid "%u vendor class: %s"
 msgstr ""
 
-#: rfc2131.c:501
+#: rfc2131.c:523
 #, c-format
 msgid "%u user class: %s"
 msgstr ""
 
-#: rfc2131.c:535
+#: rfc2131.c:557
 msgid "disabled"
 msgstr ""
 
-#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
-#: rfc3315.c:1097
+#: rfc2131.c:598 rfc2131.c:1087 rfc2131.c:1532 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1121
 msgid "ignored"
 msgstr ""
 
-#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
+#: rfc2131.c:613 rfc2131.c:1333 rfc3315.c:867
 msgid "address in use"
 msgstr ""
 
-#: rfc2131.c:605 rfc2131.c:1119
+#: rfc2131.c:627 rfc2131.c:1141
 msgid "no address available"
 msgstr ""
 
-#: rfc2131.c:612 rfc2131.c:1273
+#: rfc2131.c:634 rfc2131.c:1295
 msgid "wrong network"
 msgstr ""
 
-#: rfc2131.c:627
+#: rfc2131.c:649
 msgid "no address configured"
 msgstr ""
 
-#: rfc2131.c:633 rfc2131.c:1323
+#: rfc2131.c:655 rfc2131.c:1346
 msgid "no leases left"
 msgstr ""
 
-#: rfc2131.c:734 rfc3315.c:499
+#: rfc2131.c:756 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:864
+#: rfc2131.c:885
 msgid "PXE BIS not supported"
 msgstr ""
 
-#: rfc2131.c:1032 rfc3315.c:1197
+#: rfc2131.c:1054 rfc3315.c:1222
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr ""
 
-#: rfc2131.c:1053
+#: rfc2131.c:1075
 msgid "unknown lease"
 msgstr ""
 
-#: rfc2131.c:1088
+#: rfc2131.c:1110
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1098
+#: rfc2131.c:1120
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1101
+#: rfc2131.c:1123
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1117 rfc2131.c:1316
+#: rfc2131.c:1139 rfc2131.c:1339
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1209
+#: rfc2131.c:1231
 msgid "wrong server-ID"
 msgstr ""
 
-#: rfc2131.c:1228
+#: rfc2131.c:1250
 msgid "wrong address"
 msgstr ""
 
-#: rfc2131.c:1246 rfc3315.c:961
+#: rfc2131.c:1268 rfc3315.c:975
 msgid "lease not found"
 msgstr ""
 
-#: rfc2131.c:1281
+#: rfc2131.c:1303
 msgid "address not available"
 msgstr ""
 
-#: rfc2131.c:1292
+#: rfc2131.c:1314
 msgid "static lease available"
 msgstr ""
 
-#: rfc2131.c:1296
+#: rfc2131.c:1318
 msgid "address reserved"
 msgstr ""
 
-#: rfc2131.c:1304
+#: rfc2131.c:1327
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1845
+#: rfc2131.c:1866
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
-#: rfc2131.c:1854
+#: rfc2131.c:1875
 #, c-format
 msgid "%u server name: %s"
 msgstr ""
 
-#: rfc2131.c:1862
+#: rfc2131.c:1885
 #, c-format
 msgid "%u next server: %s"
 msgstr ""
 
-#: rfc2131.c:1865
+#: rfc2131.c:1889
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1928
+#: rfc2131.c:1952
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr ""
 
-#: rfc2131.c:2219
+#: rfc2131.c:2262
 msgid "PXE menu too large"
 msgstr ""
 
-#: rfc2131.c:2358 rfc3315.c:1470
+#: rfc2131.c:2425 rfc3315.c:1511
 #, c-format
 msgid "%u requested options: %s"
 msgstr ""
 
-#: rfc2131.c:2675
+#: rfc2131.c:2742
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2738
+#: rfc2131.c:2805
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:76
+#: netlink.c:93
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr ""
 
-#: netlink.c:352
+#: netlink.c:377
 #, c-format
 msgid "netlink returns error: %s"
 msgstr ""
 
-#: dbus.c:438
+#: dbus.c:434
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:443
+#: dbus.c:439
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:717
+#: dbus.c:713
 msgid "setting upstream servers from DBus"
 msgstr ""
 
-#: dbus.c:764
+#: dbus.c:760
 msgid "could not register a DBus message handler"
 msgstr ""
 
@@ -2000,31 +2103,36 @@ msgstr ""
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:347
+#: tftp.c:349
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:363
+#: tftp.c:365
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
-#: tftp.c:510
+#: tftp.c:512
 #, c-format
 msgid "file %s not found"
 msgstr ""
 
-#: tftp.c:628
+#: tftp.c:602
+#, c-format
+msgid "ignoring packet from %s (TID mismatch)"
+msgstr ""
+
+#: tftp.c:646
 #, c-format
 msgid "failed sending %s to %s"
 msgstr ""
 
-#: tftp.c:628
+#: tftp.c:646
 #, c-format
 msgid "sent %s to %s"
 msgstr ""
 
-#: tftp.c:678
+#: tftp.c:696
 #, c-format
 msgid "error %d %s received from %s"
 msgstr ""
@@ -2039,7 +2147,7 @@ msgstr ""
 msgid "log failed: %s"
 msgstr ""
 
-#: log.c:471
+#: log.c:477
 msgid "FAILED to start up"
 msgstr ""
 
@@ -2092,11 +2200,11 @@ msgstr ""
 msgid "address unavailable"
 msgstr ""
 
-#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1272
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913 rfc3315.c:1047
 msgid "no addresses available"
 msgstr ""
 
@@ -2104,114 +2212,114 @@ msgstr ""
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
+#: rfc3315.c:979 rfc3315.c:1180 rfc3315.c:1261
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1002
+#: rfc3315.c:1016
 msgid "deprecated"
 msgstr ""
 
-#: rfc3315.c:1007
+#: rfc3315.c:1023
 msgid "address invalid"
 msgstr ""
 
-#: rfc3315.c:1057 rfc3315.c:1059
+#: rfc3315.c:1081 rfc3315.c:1083
 msgid "confirm failed"
 msgstr ""
 
-#: rfc3315.c:1074
+#: rfc3315.c:1098
 msgid "all addresses still on link"
 msgstr ""
 
-#: rfc3315.c:1165
+#: rfc3315.c:1189
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2130
+#: rfc3315.c:2173
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
-#: dhcp-common.c:145
+#: dhcp-common.c:154
 #, c-format
 msgid "Ignoring duplicate dhcp-option %d"
 msgstr ""
 
-#: dhcp-common.c:222
+#: dhcp-common.c:231
 #, c-format
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:444
+#: dhcp-common.c:451
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
-#: dhcp-common.c:478
+#: dhcp-common.c:485
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr ""
 
-#: dhcp-common.c:542
+#: dhcp-common.c:549
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr ""
 
-#: dhcp-common.c:665
+#: dhcp-common.c:672
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:676
+#: dhcp-common.c:683
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:873
+#: dhcp-common.c:880
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:876
+#: dhcp-common.c:883
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:918
+#: dhcp-common.c:925
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
-#: dhcp-common.c:920
+#: dhcp-common.c:927
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:922
+#: dhcp-common.c:929
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
-#: dhcp-common.c:923
+#: dhcp-common.c:930
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:936
+#: dhcp-common.c:943
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:939
+#: dhcp-common.c:946
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr ""
 
-#: dhcp-common.c:950
+#: dhcp-common.c:957
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:952
+#: dhcp-common.c:959
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2221,31 +2329,119 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr ""
 
-#: auth.c:439
+#: auth.c:464
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
 
-#: ipset.c:95
+#: ipset.c:99
 #, c-format
-msgid "failed to find kernel version: %s"
+msgid "failed to create IPset control socket: %s"
 msgstr ""
 
-#: ipset.c:114
+#: ipset.c:211
 #, c-format
-msgid "failed to create IPset control socket: %s"
+msgid "failed to update ipset %s: %s"
 msgstr ""
 
-#: ipset.c:226
+#: pattern.c:29
 #, c-format
-msgid "failed to update ipset %s: %s"
+msgid "[pattern.c:%d] Assertion failure: %s"
+msgstr ""
+
+#: pattern.c:142
+#, c-format
+msgid "Invalid DNS name: Invalid character %c."
+msgstr ""
+
+#: pattern.c:151
+msgid "Invalid DNS name: Empty label."
+msgstr ""
+
+#: pattern.c:156
+msgid "Invalid DNS name: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:170
+msgid "Invalid DNS name: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:176
+#, c-format
+msgid "Invalid DNS name: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:184
+#, c-format
+msgid "Invalid DNS name: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:189
+msgid "Invalid DNS name: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:199
+msgid "Invalid DNS name: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:204
+#, c-format
+msgid "DNS name has invalid length (%zu)."
+msgstr ""
+
+#: pattern.c:258
+#, c-format
+msgid "Invalid DNS name pattern: Invalid character %c."
+msgstr ""
+
+#: pattern.c:267
+msgid "Invalid DNS name pattern: Empty label."
+msgstr ""
+
+#: pattern.c:272
+msgid "Invalid DNS name pattern: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:285
+msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+msgstr ""
+
+#: pattern.c:295
+msgid "Invalid DNS name pattern: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:301
+#, c-format
+msgid "Invalid DNS name pattern: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:309
+#, c-format
+msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:314
+msgid "Invalid DNS name pattern: Wildcard within final two labels."
+msgstr ""
+
+#: pattern.c:319
+msgid "Invalid DNS name pattern: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:329
+msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:334
+#, c-format
+msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
 msgstr ""
 
 #: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: dnssec.c:902
+#: dnssec.c:1014
 #, c-format
 msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
 msgstr ""
@@ -2277,7 +2473,7 @@ msgstr ""
 
 #: tables.c:101
 #, c-format
-msgid "IPset: error:%s"
+msgid "IPset: error: %s"
 msgstr ""
 
 #: tables.c:108
@@ -2339,51 +2535,42 @@ msgstr ""
 msgid "bad header in %s"
 msgstr ""
 
-#: dump.c:201
+#: dump.c:205
 msgid "failed to write packet dump"
 msgstr ""
 
-#: dump.c:203
+#: dump.c:207
 #, c-format
 msgid "dumping UDP packet %u mask 0x%04x"
 msgstr ""
 
-#: ubus.c:52
+#: ubus.c:79
 #, c-format
 msgid "UBus subscription callback: %s subscriber(s)"
 msgstr ""
 
-#: ubus.c:73
+#: ubus.c:99
 #, c-format
 msgid "Cannot reconnect to UBus: %s"
 msgstr ""
 
-#: ubus.c:89
-msgid "Cannot initialize UBus: connection failed"
-msgstr ""
-
-#: ubus.c:102
-#, c-format
-msgid "Cannot add object to UBus: %s"
-msgstr ""
-
-#: ubus.c:112
-msgid "Connected to system UBus"
-msgstr ""
-
-#: ubus.c:122
+#: ubus.c:135
 msgid "Cannot set UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:142
+#: ubus.c:155
 msgid "Cannot poll UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:155
+#: ubus.c:168
 msgid "Disconnecting from UBus"
 msgstr ""
 
-#: ubus.c:199
+#: ubus.c:179 ubus.c:326
 #, c-format
-msgid "Failed to send UBus event: %s"
+msgid "UBus command failed: %d (%s)"
+msgstr ""
+
+#: hash-questions.c:40
+msgid "Failed to create SHA-256 hash object"
 msgstr ""
index 85d50d9..33e80b8 100644 (file)
--- a/po/no.po
+++ b/po/no.po
@@ -18,802 +18,835 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: cache.c:559
+#: cache.c:572
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:1081
+#: cache.c:1094
 #, fuzzy, c-format
 msgid "failed to load names from %s: %s"
 msgstr "feilet å laste navn fra %s: %s"
 
-#: cache.c:1103 dhcp.c:927
+#: cache.c:1116 dhcp.c:931
 #, c-format
 msgid "bad address at %s line %d"
 msgstr "dårlig adresse ved %s linje %d"
 
-#: cache.c:1156 dhcp.c:943
+#: cache.c:1169 dhcp.c:947
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "dårlig navn ved %s linje %d"
 
-#: cache.c:1167 dhcp.c:1018
+#: cache.c:1180 dhcp.c:1022
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "les %s - %d adresser"
 
-#: cache.c:1283
+#: cache.c:1296
 msgid "cleared cache"
 msgstr "mellomlager tømt"
 
-#: cache.c:1345
+#: cache.c:1358
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1391
+#: cache.c:1404
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
-#: cache.c:1415
+#: cache.c:1428
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "gir ikke navnet %s til DHCP leien for %s fordi navnet eksisterer i %s med adressen %s"
 
-#: cache.c:1663
+#: cache.c:1674
 #, c-format
 msgid "time %lu"
 msgstr ""
 
-#: cache.c:1664
+#: cache.c:1675
 #, fuzzy, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "mellomlager størrelse %d, %d/%d mellomlager innsettinger re-bruker mellomlager plasser som ikke er utløpt"
 
-#: cache.c:1666
+#: cache.c:1677
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1669
+#: cache.c:1680
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1694
+#: cache.c:1702
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
 
-#: util.c:47
+#: util.c:51
 #, fuzzy, c-format
 msgid "failed to seed the random number generator: %s"
 msgstr "feilet å lytte på socket: %s"
 
-#: util.c:224
+#: util.c:228
 #, fuzzy
 msgid "failed to allocate memory"
 msgstr "feilet å laste %d bytes"
 
-#: util.c:281 option.c:641
+#: util.c:285 option.c:665
 msgid "could not get memory"
 msgstr "kunne ikke få minne"
 
-#: util.c:302
+#: util.c:306
 #, fuzzy, c-format
 msgid "cannot create pipe: %s"
 msgstr "kan ikke lese %s: %s"
 
-#: util.c:310
+#: util.c:314
 #, fuzzy, c-format
 msgid "failed to allocate %d bytes"
 msgstr "feilet å laste %d bytes"
 
-#: util.c:506
+#: util.c:520
 #, c-format
 msgid "infinite"
 msgstr "uendelig"
 
-#: option.c:358
+#: util.c:808
+#, fuzzy, c-format
+msgid "failed to find kernel version: %s"
+msgstr "feilet å binde DHCP tjener socket: %s"
+
+#: option.c:372
 msgid "Specify local address(es) to listen on."
 msgstr "Spesifiser lokal(e) adresse(r) å lytte på."
 
-#: option.c:359
+#: option.c:373
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Returner ipaddr for alle verter i det spesifiserte domenet."
 
-#: option.c:360
+#: option.c:374
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Forfalsk revers oppslag for RFC1918 private adresse områder."
 
-#: option.c:361
+#: option.c:375
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Behandle ipaddr som NXDOMAIN (omgår Verisign wildcard)."
 
-#: option.c:362
+#: option.c:376
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Spesifiser størrelsen på mellomlager plassene (standard er %s)."
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Spesifiser konfigurasjonsfil (standard er %s)."
 
-#: option.c:364
+#: option.c:378
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "IKKE legg (fork) som bakgrunnsprosess: kjør i debug modus."
 
-#: option.c:365
+#: option.c:379
 msgid "Do NOT forward queries with no domain part."
 msgstr "IKKE videresend oppslag som mangler domene del."
 
-#: option.c:366
+#: option.c:380
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Returner selv-pekende MX post for lokale verter."
 
-#: option.c:367
+#: option.c:381
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Utvid enkle navn i /etc/hosts med domene-suffiks."
 
-#: option.c:368
+#: option.c:382
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "Ikke videresend falske/uekte DNS forespørsler fra Windows verter."
 
-#: option.c:369
+#: option.c:383
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Aktiver DHCP i det gitte området med leie varighet"
 
-#: option.c:370
+#: option.c:384
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Skift til denne gruppen etter oppstart (standard er %s)."
 
-#: option.c:371
+#: option.c:385
 msgid "Set address or hostname for a specified machine."
 msgstr "Sett adresse eller vertsnavn for en spesifikk maskin."
 
-#: option.c:372
+#: option.c:386
 #, fuzzy
 msgid "Read DHCP host specs from file."
 msgstr "dårlig MX navn"
 
-#: option.c:373
+#: option.c:387
 msgid "Read DHCP option specs from file."
 msgstr ""
 
-#: option.c:374
+#: option.c:388
 #, fuzzy
 msgid "Read DHCP host specs from a directory."
 msgstr "dårlig MX navn"
 
-#: option.c:375
+#: option.c:389
 #, fuzzy
 msgid "Read DHCP options from a directory."
 msgstr "dårlig MX navn"
 
-#: option.c:376
+#: option.c:390
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
-#: option.c:377
+#: option.c:391
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "IKKE last %s filen."
 
-#: option.c:378
+#: option.c:392
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Spesifiser en verts (hosts) fil som skal leses i tilleg til %s."
 
-#: option.c:379
+#: option.c:393
 #, fuzzy
 msgid "Read hosts files from a directory."
 msgstr "dårlig MX navn"
 
-#: option.c:380
+#: option.c:394
 msgid "Specify interface(s) to listen on."
 msgstr "Spesifiser nettverkskort det skal lyttes på."
 
-#: option.c:381
+#: option.c:395
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Spesifiser nettverkskort det IKKE skal lyttes på."
 
-#: option.c:382
+#: option.c:396
 #, fuzzy
 msgid "Map DHCP user class to tag."
 msgstr "Map DHCP bruker klasse til opsjon sett."
 
-#: option.c:383
+#: option.c:397
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:384
+#: option.c:398
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
-#: option.c:386
+#: option.c:400
+msgid "Specify vendor class to match for PXE requests."
+msgstr ""
+
+#: option.c:401
 #, fuzzy
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Ikke utfør DHCP for klienter i opsjon sett."
 
-#: option.c:387
+#: option.c:402
 #, fuzzy
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Ikke utfør DHCP for klienter i opsjon sett."
 
-#: option.c:388
+#: option.c:403
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "IKKE last (fork) som bakgrunnsprosess, IKKE kjør i debug modus."
 
-#: option.c:389
+#: option.c:404
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Anta at vi er den eneste DHCP tjeneren på det lokale nettverket."
 
-#: option.c:390
+#: option.c:405
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Spesifiser hvor DHCP leiene skal lagres (standard er %s)."
 
-#: option.c:391
+#: option.c:406
 msgid "Return MX records for local hosts."
 msgstr "Returner MX records for lokale verter."
 
-#: option.c:392
+#: option.c:407
 msgid "Specify an MX record."
 msgstr "Spesifiser en MX post."
 
-#: option.c:393
+#: option.c:408
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Spesifiser BOOTP opsjoner til DHCP tjener."
 
-#: option.c:394
+#: option.c:409
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "IKKE spør (poll) %s fil, les på nytt kun ved SIGHUP"
 
-#: option.c:395
+#: option.c:410
 msgid "Do NOT cache failed search results."
 msgstr "IKKE mellomlagre søkeresultater som feiler."
 
-#: option.c:396
+#: option.c:411
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Bruk navnetjenere kun som bestemt i rekkefølgen gitt i %s."
 
-#: option.c:397
+#: option.c:412
 #, fuzzy
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Sett ekstra opsjoner som skal fordeles til DHCP klientene."
 
-#: option.c:398
+#: option.c:413
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
-#: option.c:399
+#: option.c:414
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Spesifiser lytteport for DNS oppslag (standard er 53)."
 
-#: option.c:400
+#: option.c:415
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Maksimal støttet UDP pakkestørrelse for EDNS.0 (standard er %s)."
 
-#: option.c:401
+#: option.c:416
 #, fuzzy
 msgid "Log DNS queries."
 msgstr "Logg oppslag."
 
-#: option.c:402
+#: option.c:417
 #, fuzzy
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Tving bruk av opprinnelig port for oppstrøms oppslag."
 
-#: option.c:403
+#: option.c:418
 msgid "Do NOT read resolv.conf."
 msgstr "IKKE les resolv.conf."
 
-#: option.c:404
+#: option.c:419
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Spesifiser stien til resolv.conf (standard er %s)."
 
-#: option.c:405
+#: option.c:420
 #, fuzzy
 msgid "Specify path to file with server= options"
 msgstr "Spesifiser stien til PID fil. (standard er %s)."
 
-#: option.c:406
+#: option.c:421
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Spesifiser adressen(e) til oppstrøms tjenere med valgfrie domener."
 
-#: option.c:407
+#: option.c:422
 #, fuzzy
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Spesifiser adressen(e) til oppstrøms tjenere med valgfrie domener."
 
-#: option.c:408
+#: option.c:423
 msgid "Never forward queries to specified domains."
 msgstr "Aldri videresend oppslag til spesifiserte domener."
 
-#: option.c:409
+#: option.c:424
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Spesifiser domenet som skal tildeles i DHCP leien."
 
-#: option.c:410
+#: option.c:425
 msgid "Specify default target in an MX record."
 msgstr "Spesifiser default mål i en MX post."
 
-#: option.c:411
+#: option.c:426
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Spesifiser time-to-live i sekunder for svar fra /etc/hosts."
 
-#: option.c:412
+#: option.c:427
 #, fuzzy
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Spesifiser time-to-live i sekunder for svar fra /etc/hosts."
 
-#: option.c:413
+#: option.c:428
 #, fuzzy
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Spesifiser time-to-live i sekunder for svar fra /etc/hosts."
 
-#: option.c:414
+#: option.c:429
 #, fuzzy
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Spesifiser time-to-live i sekunder for svar fra /etc/hosts."
 
-#: option.c:415
+#: option.c:430
 #, fuzzy
 msgid "Specify time-to-live floor for cache."
 msgstr "Spesifiser time-to-live i sekunder for svar fra /etc/hosts."
 
-#: option.c:416
+#: option.c:431
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Skift til denne bruker etter oppstart (standard er %s)."
 
-#: option.c:417
+#: option.c:432
 #, fuzzy
 msgid "Map DHCP vendor class to tag."
 msgstr "Map DHCP produsent klasse til opsjon sett."
 
-#: option.c:418
+#: option.c:433
 msgid "Display dnsmasq version and copyright information."
 msgstr "Vis dnsmasq versjon og copyright informasjon."
 
-#: option.c:419
+#: option.c:434
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Oversett IPv4 adresser fra oppstrøms tjenere."
 
-#: option.c:420
+#: option.c:435
 msgid "Specify a SRV record."
 msgstr "Spesifiser en SRV post."
 
-#: option.c:421
+#: option.c:436
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
-#: option.c:422
+#: option.c:437
 #, fuzzy, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Spesifiser stien til PID fil. (standard er %s)."
 
-#: option.c:423
+#: option.c:438
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
 
-#: option.c:424
+#: option.c:439
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Svar DNS oppslag basert på nettverkskortet oppslaget ble sendt til."
 
-#: option.c:425
+#: option.c:440
 msgid "Specify TXT DNS record."
 msgstr "Spesifiser TXT DNS post."
 
-#: option.c:426
+#: option.c:441
 #, fuzzy
 msgid "Specify PTR DNS record."
 msgstr "Spesifiser TXT DNS post."
 
-#: option.c:427
+#: option.c:442
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
-#: option.c:428
+#: option.c:443
 msgid "Bind only to interfaces in use."
 msgstr "Bind kun til nettverkskort som er i bruk."
 
-#: option.c:429
+#: option.c:444
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Les DHCP statisk vert informasjon fra %s."
 
-#: option.c:430
+#: option.c:445
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Aktiver DBus interface for å sette oppstrøms tjenere, osv."
 
-#: option.c:431
+#: option.c:446
 msgid "Enable the UBus interface."
 msgstr ""
 
-#: option.c:432
+#: option.c:447
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "Ikke lever DHCP på dette nettverkskortet, kun lever DNS."
 
-#: option.c:433
+#: option.c:448
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Aktiver dynamisk adresse allokering for bootp."
 
-#: option.c:434
+#: option.c:449
 #, fuzzy
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Map DHCP produsent klasse til opsjon sett."
 
-#: option.c:435
+#: option.c:450
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:436
+#: option.c:451
 msgid "Specify extra networks sharing a broadcast domain for DHCP"
 msgstr ""
 
-#: option.c:437
+#: option.c:452
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:438
+#: option.c:453
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:439
+#: option.c:454
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:440
+#: option.c:455
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:441
+#: option.c:456
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:442
+#: option.c:457
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
-#: option.c:443
+#: option.c:458
 #, fuzzy
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Skift til denne bruker etter oppstart (standard er %s)."
 
-#: option.c:444
+#: option.c:459
 msgid "Do not use leasefile."
 msgstr ""
 
-#: option.c:445
+#: option.c:460
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
 
-#: option.c:446
+#: option.c:461
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:447
+#: option.c:462
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:448
+#: option.c:463
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:449
+#: option.c:464
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:450
+#: option.c:465
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:451
+#: option.c:466
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:452
+#: option.c:467
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:453
+#: option.c:468
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:454
+#: option.c:469
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
 
-#: option.c:455
+#: option.c:470
 #, fuzzy
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
 
-#: option.c:456
+#: option.c:471
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:457
+#: option.c:472
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:458
+#: option.c:473
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:459
+#: option.c:474
 msgid "Use only one port for TFTP server."
 msgstr ""
 
-#: option.c:460
+#: option.c:475
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:461
+#: option.c:476
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:462
+#: option.c:477
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:463
+#: option.c:478
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:464
+#: option.c:479
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:465
+#: option.c:480
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:466
+#: option.c:481
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:467
+#: option.c:482
 msgid "Set tag if client provides given name."
 msgstr ""
 
-#: option.c:468
+#: option.c:483
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
-#: option.c:469
+#: option.c:484
 #, fuzzy
 msgid "Specify NAPTR DNS record."
 msgstr "Spesifiser TXT DNS post."
 
-#: option.c:470
+#: option.c:485
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:471
+#: option.c:486
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:472
+#: option.c:487
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:473
+#: option.c:488
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:474
+#: option.c:489
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:475
+#: option.c:490
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:476
+#: option.c:491
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
-#: option.c:477
+#: option.c:492
 #, fuzzy
 msgid "Prompt to send to PXE clients."
 msgstr "Sett ekstra opsjoner som skal fordeles til DHCP klientene."
 
-#: option.c:478
+#: option.c:493
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:479
+#: option.c:494
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:480
+#: option.c:495
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:481
+#: option.c:496
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
-#: option.c:482
+#: option.c:497
 #, fuzzy
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Tving bruk av opprinnelig port for oppstrøms oppslag."
 
-#: option.c:483
+#: option.c:498
 #, fuzzy
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Oversett IPv4 adresser fra oppstrøms tjenere."
 
-#: option.c:484
+#: option.c:499
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:485
+#: option.c:500
 #, fuzzy
 msgid "Ignore client identifier option sent by DHCP clients."
 msgstr "Sett ekstra opsjoner som skal fordeles til DHCP klientene."
 
-#: option.c:486
+#: option.c:501
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:487
+#: option.c:502
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:488
+#: option.c:503
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:489
+#: option.c:504
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:490
+#: option.c:505
 #, fuzzy
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Spesifiser en MX post."
 
-#: option.c:491
+#: option.c:506
+msgid "Specify host record in interface subnet"
+msgstr ""
+
+#: option.c:507
 msgid "Specify certification authority authorization record"
 msgstr ""
 
-#: option.c:492
+#: option.c:508
 #, fuzzy
 msgid "Specify arbitrary DNS resource record"
 msgstr "Spesifiser TXT DNS post."
 
-#: option.c:493
+#: option.c:509
 #, fuzzy
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "ukjent tilknytning (interface) %s"
 
-#: option.c:494
+#: option.c:510
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:495
+#: option.c:511
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:496
+#: option.c:512
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:497
+#: option.c:513
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:498
+#: option.c:514
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:499
+#: option.c:515
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:500
+#: option.c:516
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:501
+#: option.c:517
+msgid "Enable filtering of DNS queries with connection-track marks."
+msgstr ""
+
+#: option.c:518
+msgid "Set allowed DNS patterns for a connection-track mark."
+msgstr ""
+
+#: option.c:519
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:502
+#: option.c:520
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:503
+#: option.c:521
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:504
+#: option.c:522
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:505
+#: option.c:523
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:506
+#: option.c:524
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:507
+#: option.c:525
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:508
+#: option.c:526
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:509
+#: option.c:527
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:510
+#: option.c:528
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:511
+#: option.c:529
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:512
+#: option.c:530
+msgid "Log debugging information."
+msgstr ""
+
+#: option.c:531
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:513
+#: option.c:532
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:514
+#: option.c:533
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:515
+#: option.c:534
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:516
+#: option.c:535
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:517
+#: option.c:536
 msgid "Enables DHCPv4 Rapid Commit option."
 msgstr ""
 
-#: option.c:518
+#: option.c:537
 msgid "Path to debug packet dump file"
 msgstr ""
 
-#: option.c:519
+#: option.c:538
 msgid "Mask which packets to dump"
 msgstr ""
 
-#: option.c:520
+#: option.c:539
 msgid "Call dhcp-script when lease expiry changes."
 msgstr ""
 
-#: option.c:725
+#: option.c:540
+msgid "Send Cisco Umbrella identifiers including remote IP."
+msgstr ""
+
+#: option.c:541
+msgid "Do not log routine TFTP."
+msgstr ""
+
+#: option.c:771
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -822,356 +855,397 @@ msgstr ""
 "Bruk: dnsmasq [opsjoner]\n"
 "\n"
 
-#: option.c:727
+#: option.c:773
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Bruk korte opsjoner kun på kommandolinjen.\n"
 
-#: option.c:729
+#: option.c:775
 #, fuzzy, c-format
 msgid "Valid options are:\n"
 msgstr "Gyldige opsjoner er :\n"
 
-#: option.c:776 option.c:884
+#: option.c:822 option.c:933
 #, fuzzy
 msgid "bad address"
 msgstr "les %s - %d adresser"
 
-#: option.c:799 option.c:803
+#: option.c:847 option.c:851
 msgid "bad port"
 msgstr "dårlig port"
 
-#: option.c:815 option.c:844 option.c:878
+#: option.c:864 option.c:893 option.c:927
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:839 option.c:873
+#: option.c:888 option.c:922
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:852 option.c:4042
+#: option.c:901 option.c:4362
 #, fuzzy
 msgid "bad interface name"
 msgstr "dårlig MX navn"
 
-#: option.c:1184
+#: option.c:1192
+msgid "inappropriate vendor:"
+msgstr ""
+
+#: option.c:1199
+msgid "inappropriate encap:"
+msgstr ""
+
+#: option.c:1225
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
-#: option.c:1198
+#: option.c:1239
 msgid "bad dhcp-option"
 msgstr "dårlig dhcp-opsjon"
 
-#: option.c:1270
+#: option.c:1317
 #, fuzzy
 msgid "bad IP address"
 msgstr "les %s - %d adresser"
 
-#: option.c:1273 option.c:1412 option.c:3297
+#: option.c:1320 option.c:1459 option.c:3551
 #, fuzzy
 msgid "bad IPv6 address"
 msgstr "les %s - %d adresser"
 
-#: option.c:1366
+#: option.c:1413
 #, fuzzy
 msgid "bad IPv4 address"
 msgstr "les %s - %d adresser"
 
-#: option.c:1439 option.c:1533
+#: option.c:1486 option.c:1581
 msgid "bad domain in dhcp-option"
 msgstr "dårlig domene i dhcp-opsjon"
 
-#: option.c:1571
+#: option.c:1625
 msgid "dhcp-option too long"
 msgstr "dhcp-opsjon for lang"
 
-#: option.c:1578
+#: option.c:1632
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1647
+#: option.c:1691
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1655
+#: option.c:1699
 msgid "illegal repeated keyword"
 msgstr ""
 
-#: option.c:1726 option.c:4764
+#: option.c:1770 option.c:5080
 #, fuzzy, c-format
 msgid "cannot access directory %s: %s"
 msgstr "kan ikke lese %s: %s"
 
-#: option.c:1772 tftp.c:564 dump.c:68
+#: option.c:1816 tftp.c:566 dump.c:68
 #, fuzzy, c-format
 msgid "cannot access %s: %s"
 msgstr "kan ikke lese %s: %s"
 
-#: option.c:1879
+#: option.c:1931
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1888
+#: option.c:1940
 msgid "bad log facility"
 msgstr ""
 
-#: option.c:1941
+#: option.c:1993
 msgid "bad MX preference"
 msgstr "dårlig MX preferanse"
 
-#: option.c:1946
+#: option.c:1998
 msgid "bad MX name"
 msgstr "dårlig MX navn"
 
-#: option.c:1960
+#: option.c:2012
 msgid "bad MX target"
 msgstr "dårlig MX mål"
 
-#: option.c:1980
+#: option.c:2032
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1984
+#: option.c:2036
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
-#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
+#: option.c:2291 option.c:2327
+#, fuzzy
+msgid "bad prefix length"
+msgstr "dårlig port"
+
+#: option.c:2303 option.c:2348 option.c:2398
 #, fuzzy
 msgid "bad prefix"
 msgstr "dårlig port"
 
-#: option.c:2658
+#: option.c:2418
+msgid "prefix length too small"
+msgstr ""
+
+#: option.c:2697
+#, fuzzy
+msgid "Bad address in --address"
+msgstr "adresse i bruk"
+
+#: option.c:2751
+#, fuzzy
+msgid "bad IPv4 prefix"
+msgstr "dårlig port"
+
+#: option.c:2756 option.c:3569
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "dårlig port"
+
+#: option.c:2777
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
-#: option.c:2871
+#: option.c:2843 option.c:2861
+msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+msgstr ""
+
+#: option.c:3119
 #, fuzzy
 msgid "bad port range"
 msgstr "dårlig port"
 
-#: option.c:2897
+#: option.c:3145
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2941
+#: option.c:3189
 msgid "bad shared-network"
 msgstr ""
 
-#: option.c:2996
+#: option.c:3243
 msgid "only one tag allowed"
 msgstr ""
 
-#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
+#: option.c:3264 option.c:3280 option.c:3406 option.c:3414 option.c:3457
 msgid "bad dhcp-range"
 msgstr "dårlig dhcp-område"
 
-#: option.c:3050
+#: option.c:3298
 msgid "inconsistent DHCP range"
 msgstr "ikke konsistent DHCP område"
 
-#: option.c:3115
+#: option.c:3364
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:3117
+#: option.c:3366
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:3120
+#: option.c:3369
 msgid "prefix length must be at least 64"
 msgstr ""
 
-#: option.c:3123
+#: option.c:3372
 #, fuzzy
 msgid "inconsistent DHCPv6 range"
 msgstr "ikke konsistent DHCP område"
 
-#: option.c:3142
+#: option.c:3391
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
-#: option.c:3262 option.c:3340
+#: option.c:3516 option.c:3594
 #, fuzzy
 msgid "bad hex constant"
 msgstr "dårlig dhcp-vert"
 
-#: option.c:3315
-#, fuzzy
-msgid "bad IPv6 prefix"
-msgstr "dårlig port"
-
-#: option.c:3362
+#: option.c:3617
 #, fuzzy, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "dubliserte IP adresser i %s dhcp-config direktiv."
 
-#: option.c:3422
+#: option.c:3678
 #, fuzzy
 msgid "bad DHCP host name"
 msgstr "dårlig MX navn"
 
-#: option.c:3508
+#: option.c:3764
 #, fuzzy
 msgid "bad tag-if"
 msgstr "dårlig MX mål"
 
-#: option.c:3851 option.c:4324
+#: option.c:4107 option.c:4623
 msgid "invalid port number"
 msgstr "ugyldig portnummer"
 
-#: option.c:3907
+#: option.c:4163
 #, fuzzy
 msgid "bad dhcp-proxy address"
 msgstr "les %s - %d adresser"
 
-#: option.c:3935
+#: option.c:4204
 #, fuzzy
 msgid "Bad dhcp-relay"
 msgstr "dårlig dhcp-område"
 
-#: option.c:3979
+#: option.c:4248
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3989
+#: option.c:4258
 msgid "bad DUID"
 msgstr ""
 
-#: option.c:4023
+#: option.c:4292
 #, fuzzy
 msgid "missing address in alias"
 msgstr "adresse i bruk"
 
-#: option.c:4029
+#: option.c:4298
 #, fuzzy
 msgid "invalid alias range"
 msgstr "ugyldig vekt"
 
-#: option.c:4081 option.c:4097
+#: option.c:4347
+#, fuzzy
+msgid "missing address in dynamic host"
+msgstr "adresse i bruk"
+
+#: option.c:4362
+#, fuzzy
+msgid "bad dynamic host"
+msgstr "kan ikke lese %s: %s"
+
+#: option.c:4380 option.c:4396
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:4105
+#: option.c:4404
 msgid "duplicate CNAME"
 msgstr ""
 
-#: option.c:4132
+#: option.c:4431
 #, fuzzy
 msgid "bad PTR record"
 msgstr "dårlig SRV post"
 
-#: option.c:4167
+#: option.c:4466
 #, fuzzy
 msgid "bad NAPTR record"
 msgstr "dårlig SRV post"
 
-#: option.c:4203
+#: option.c:4502
 #, fuzzy
 msgid "bad RR record"
 msgstr "dårlig SRV post"
 
-#: option.c:4236
+#: option.c:4535
 #, fuzzy
 msgid "bad CAA record"
 msgstr "dårlig SRV post"
 
-#: option.c:4265
+#: option.c:4564
 msgid "bad TXT record"
 msgstr "dårlig TXT post"
 
-#: option.c:4308
+#: option.c:4607
 msgid "bad SRV record"
 msgstr "dårlig SRV post"
 
-#: option.c:4315
+#: option.c:4614
 msgid "bad SRV target"
 msgstr "dårlig SRV mål"
 
-#: option.c:4334
+#: option.c:4633
 msgid "invalid priority"
 msgstr "ugyldig prioritet"
 
-#: option.c:4339
+#: option.c:4638
 msgid "invalid weight"
 msgstr "ugyldig vekt"
 
-#: option.c:4362
+#: option.c:4661
 #, fuzzy
 msgid "Bad host-record"
 msgstr "dårlig SRV post"
 
-#: option.c:4402
+#: option.c:4700
 #, fuzzy
 msgid "Bad name in host-record"
 msgstr "dårlig navn i %s"
 
-#: option.c:4444
+#: option.c:4742
 msgid "bad value for dnssec-check-unsigned"
 msgstr ""
 
-#: option.c:4480
+#: option.c:4778
 #, fuzzy
 msgid "bad trust anchor"
 msgstr "dårlig port"
 
-#: option.c:4496
+#: option.c:4794
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4507
+#: option.c:4805
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
-#: option.c:4567
+#: option.c:4865
 msgid "missing \""
 msgstr "mangler \""
 
-#: option.c:4624
+#: option.c:4922
 msgid "bad option"
 msgstr "dårlig opsjon"
 
-#: option.c:4626
+#: option.c:4924
 msgid "extraneous parameter"
 msgstr "overflødig parameter"
 
-#: option.c:4628
+#: option.c:4926
 msgid "missing parameter"
 msgstr "mangler parameter"
 
-#: option.c:4630
+#: option.c:4928
 #, fuzzy
 msgid "illegal option"
 msgstr "dårlig opsjon"
 
-#: option.c:4637
+#: option.c:4935
 msgid "error"
 msgstr "feil"
 
-#: option.c:4639
+#: option.c:4937
 #, fuzzy, c-format
 msgid " at line %d of %s"
 msgstr "%s på linje %d av %%s"
 
-#: option.c:4654 option.c:4939 option.c:4950
+#: option.c:4952 option.c:5229 option.c:5240
 #, fuzzy, c-format
 msgid "read %s"
 msgstr "leser %s"
 
-#: option.c:4717 option.c:4840 tftp.c:754
+#: option.c:5015 option.c:5162 tftp.c:775
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "kan ikke lese %s: %s"
 
-#: option.c:5027
+#: option.c:5316
 msgid "junk found in command line"
 msgstr ""
 
-#: option.c:5067
+#: option.c:5356
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Dnsmasq versjon %s %s\n"
 
-#: option.c:5068
+#: option.c:5357
 #, fuzzy, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1180,559 +1254,594 @@ msgstr ""
 "Kompileringsopsjoner %s\n"
 "\n"
 
-#: option.c:5069
+#: option.c:5358
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Denne programvaren kommer med ABSOLUTT INGEN GARANTI.\n"
 
-#: option.c:5070
+#: option.c:5359
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "DNsmasq er fri programvare, du er velkommen til å redistribuere den\n"
 
-#: option.c:5071
+#: option.c:5360
 #, fuzzy, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "under vilkårene gitt i GNU General Public License, versjon 2.\n"
 
-#: option.c:5088
+#: option.c:5377
 msgid "try --help"
 msgstr ""
 
-#: option.c:5090
+#: option.c:5379
 msgid "try -w"
 msgstr ""
 
-#: option.c:5092
+#: option.c:5381
 #, fuzzy, c-format
 msgid "bad command line options: %s"
 msgstr "dårlige kommandlinje opsjoner: %s."
 
-#: option.c:5161
+#: option.c:5450
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:5195
+#: option.c:5491
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "klarer ikke å få vertsnavn: %s"
 
-#: option.c:5223
+#: option.c:5519
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "kun en resolv.conf fil tillat i no-poll modus."
 
-#: option.c:5233
+#: option.c:5529
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "må ha nøyaktig en resolv.conf å lese domene fra."
 
-#: option.c:5236 network.c:1594 dhcp.c:876
+#: option.c:5532 network.c:1670 dhcp.c:880
 #, fuzzy, c-format
 msgid "failed to read %s: %s"
 msgstr "feilet å lese %s: %s"
 
-#: option.c:5253
+#: option.c:5549
 #, c-format
 msgid "no search directive found in %s"
 msgstr "intet søke direktiv funnet i %s"
 
-#: option.c:5274
+#: option.c:5570
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:5283
+#: option.c:5579
 msgid "syntax check OK"
 msgstr ""
 
-#: forward.c:99
+#: forward.c:104
 #, fuzzy, c-format
 msgid "failed to send packet: %s"
 msgstr "feilet å lytte på socket: %s"
 
-#: forward.c:614
+#: forward.c:601
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:677
+#: forward.c:666
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "navnetjener %s nektet å gjøre et rekursivt oppslag"
 
-#: forward.c:709
+#: forward.c:702
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:961
+#: forward.c:1074
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1370 forward.c:1830
+#: forward.c:1381 forward.c:1910
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2321
+#: forward.c:2198
+#, fuzzy, c-format
+msgid "failed to bind server socket to %s: %s"
+msgstr "feilet å binde lytte socket for %s: %s"
+
+#: forward.c:2494
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
 
-#: network.c:698
+#: forward.c:2496
+#, fuzzy, c-format
+msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
+
+#: network.c:670
+#, c-format
+msgid "stopped listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:867
 #, fuzzy, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "feilet å lage lytte socket: %s"
 
-#: network.c:1002
+#: network.c:1148
+#, c-format
+msgid "listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:1175
+#, fuzzy, c-format
+msgid "listening on %s port %d"
+msgstr "feilet å lese %s: %s"
+
+#: network.c:1208
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1009
+#: network.c:1215
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1018
+#: network.c:1224
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "advarsel: nettverkskort %s eksisterer ikke for tiden"
 
-#: network.c:1027
+#: network.c:1233
 #, fuzzy, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "benytter lokale adresser kun for %s %s"
 
-#: network.c:1085
+#: network.c:1291
 #, fuzzy, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "feilet å binde DHCP tjener socket: %s"
 
-#: network.c:1090
+#: network.c:1296
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1307
+#: network.c:1492
 #, fuzzy, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "feilet å binde lytte socket for %s: %s"
 
-#: network.c:1499
+#: network.c:1569
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignorerer navnetjener %s - lokal tilknytning"
 
-#: network.c:1510
+#: network.c:1580
 #, fuzzy, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignorerer navnetjener %s - kan ikke lage/dinde socket: %s"
 
-#: network.c:1530
+#: network.c:1598
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1533
+#: network.c:1601
 msgid "unqualified"
 msgstr "ikke kvalifisert"
 
-#: network.c:1533
+#: network.c:1601
 msgid "names"
 msgstr ""
 
-#: network.c:1535
+#: network.c:1603
 msgid "default"
 msgstr ""
 
-#: network.c:1537
+#: network.c:1605
 msgid "domain"
 msgstr "domene"
 
-#: network.c:1543
+#: network.c:1607
 #, fuzzy, c-format
-msgid "using only locally-known addresses for %s %s"
-msgstr "benytter lokale adresser kun for %s %s"
-
-#: network.c:1546
-#, fuzzy, c-format
-msgid "using standard nameservers for %s %s"
+msgid "using nameserver %s#%d for %s %s%s %s"
 msgstr "benytter navnetjener %s#%d for %s %s"
 
-#: network.c:1548
-#, fuzzy, c-format
-msgid "using nameserver %s#%d for %s %s %s"
-msgstr "benytter navnetjener %s#%d for %s %s"
-
-#: network.c:1552
+#: network.c:1611
 #, fuzzy, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "benytter navnetjener %s#%d for %s %s"
 
-#: network.c:1555
+#: network.c:1614
 #, fuzzy, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "benytter navnetjener %s#%d"
 
-#: network.c:1557
+#: network.c:1616
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "benytter navnetjener %s#%d"
 
-#: network.c:1562
+#: network.c:1630
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s"
+msgstr "benytter lokale adresser kun for %s %s"
+
+#: network.c:1633
+#, fuzzy, c-format
+msgid "using standard nameservers for %s"
+msgstr "benytter navnetjener %s#%d for %s %s"
+
+#: network.c:1637
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "benytter navnetjener %s#%d"
 
-#: network.c:1564
+#: network.c:1639
 #, fuzzy, c-format
 msgid "using %d more nameservers"
 msgstr "benytter navnetjener %s#%d"
 
-#: dnsmasq.c:173
+#: dnsmasq.c:184
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:188
+#: dnsmasq.c:199
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:202
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:193
+#: dnsmasq.c:204
 #, fuzzy
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:199
+#: dnsmasq.c:210
 #, fuzzy
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:204
+#: dnsmasq.c:217
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
-#: dnsmasq.c:207
+#: dnsmasq.c:223
 #, fuzzy
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:212
+#: dnsmasq.c:228
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:217
+#: dnsmasq.c:233
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
-#: dnsmasq.c:222
+#: dnsmasq.c:238
 #, fuzzy
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:227
+#: dnsmasq.c:243
 #, fuzzy
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:232
+#: dnsmasq.c:248
 #, fuzzy
 msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:236
+#: dnsmasq.c:259
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:243
+#: dnsmasq.c:266
 msgid "--auth-server required when an auth zone is defined."
 msgstr ""
 
-#: dnsmasq.c:248
+#: dnsmasq.c:271
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:268
+#: dnsmasq.c:291
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:332
+#: dnsmasq.c:355
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
-#: dnsmasq.c:335
+#: dnsmasq.c:358
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "feilet å finne liste av tilknytninger (interfaces): %s"
 
-#: dnsmasq.c:344
+#: dnsmasq.c:367
 #, c-format
 msgid "unknown interface %s"
 msgstr "ukjent tilknytning (interface) %s"
 
-#: dnsmasq.c:406
+#: dnsmasq.c:437
 #, fuzzy
 msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:416 dnsmasq.c:1171
+#: dnsmasq.c:445 dnsmasq.c:1207
 #, c-format
 msgid "DBus error: %s"
 msgstr "DBus feil: %s"
 
-#: dnsmasq.c:419
+#: dnsmasq.c:448
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:429
+#: dnsmasq.c:456 dnsmasq.c:1228
+#, fuzzy, c-format
+msgid "UBus error: %s"
+msgstr "DBus feil: %s"
+
+#: dnsmasq.c:459
 #, fuzzy
 msgid "UBus not available: set HAVE_UBUS in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:459
+#: dnsmasq.c:489
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:535
+#: dnsmasq.c:565
 #, c-format
 msgid "process is missing required capability %s"
 msgstr ""
 
-#: dnsmasq.c:567
+#: dnsmasq.c:597
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
-#: dnsmasq.c:815
+#: dnsmasq.c:845
 #, fuzzy, c-format
 msgid "started, version %s DNS disabled"
 msgstr "startet, versjon %s mellomlager deaktivert"
 
-#: dnsmasq.c:820
+#: dnsmasq.c:850
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "startet, versjon %s mellomlager størrelse %d"
 
-#: dnsmasq.c:822
+#: dnsmasq.c:852
 msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
 msgstr ""
 
-#: dnsmasq.c:825
+#: dnsmasq.c:855
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "startet, versjon %s mellomlager deaktivert"
 
-#: dnsmasq.c:828
+#: dnsmasq.c:858
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:831
+#: dnsmasq.c:861
 #, c-format
 msgid "compile time options: %s"
 msgstr "kompilerings opsjoner: %s"
 
-#: dnsmasq.c:840
+#: dnsmasq.c:870
 msgid "DBus support enabled: connected to system bus"
 msgstr "DBus støtte aktivert: koblet til system buss"
 
-#: dnsmasq.c:842
+#: dnsmasq.c:872
 msgid "DBus support enabled: bus connection pending"
 msgstr "DBus støtte aktivert: avventer buss tilkobling"
 
-#: dnsmasq.c:850
+#: dnsmasq.c:880
 #, fuzzy
 msgid "UBus support enabled: connected to system bus"
 msgstr "DBus støtte aktivert: koblet til system buss"
 
-#: dnsmasq.c:852
+#: dnsmasq.c:882
 #, fuzzy
 msgid "UBus support enabled: bus connection pending"
 msgstr "DBus støtte aktivert: avventer buss tilkobling"
 
-#: dnsmasq.c:872
+#: dnsmasq.c:902
 msgid "DNSSEC validation enabled but all unsigned answers are trusted"
 msgstr ""
 
-#: dnsmasq.c:874
+#: dnsmasq.c:904
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:878
+#: dnsmasq.c:908
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:881
+#: dnsmasq.c:911
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:884
+#: dnsmasq.c:914
 #, c-format
 msgid "configured with trust anchor for %s keytag %u"
 msgstr ""
 
-#: dnsmasq.c:890
+#: dnsmasq.c:920
 #, fuzzy, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "feilet å laste navn fra %s: %s"
 
-#: dnsmasq.c:894
+#: dnsmasq.c:924
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "setter --bind-interfaces opsjon på grunn av OS begrensninger"
 
-#: dnsmasq.c:906
+#: dnsmasq.c:936
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "advarsel: nettverkskort %s eksisterer ikke for tiden"
 
-#: dnsmasq.c:911
+#: dnsmasq.c:941
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
-#: dnsmasq.c:914
+#: dnsmasq.c:944
 #, fuzzy
 msgid "warning: no upstream servers configured"
 msgstr "setter oppstrøms tjener fra DBus"
 
-#: dnsmasq.c:918
+#: dnsmasq.c:948
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:939
+#: dnsmasq.c:969
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:944
+#: dnsmasq.c:974
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "root is "
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 #, fuzzy
 msgid "enabled"
 msgstr "deaktivert"
 
-#: dnsmasq.c:960
+#: dnsmasq.c:993
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:961
+#: dnsmasq.c:994
 #, fuzzy
 msgid "single port mode"
 msgstr "ugyldig portnummer"
 
-#: dnsmasq.c:964
+#: dnsmasq.c:997
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:968
+#: dnsmasq.c:1001
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:994
+#: dnsmasq.c:1027
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
-#: dnsmasq.c:1173
+#: dnsmasq.c:1204
 msgid "connected to system DBus"
 msgstr "tilkoblet til system DBus"
 
-#: dnsmasq.c:1345
+#: dnsmasq.c:1225
+#, fuzzy
+msgid "connected to system UBus"
+msgstr "tilkoblet til system DBus"
+
+#: dnsmasq.c:1391
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
-#: dnsmasq.c:1349
+#: dnsmasq.c:1395
 #, fuzzy, c-format
 msgid "failed to create helper: %s"
 msgstr "feilet å lese %s: %s"
 
-#: dnsmasq.c:1353
+#: dnsmasq.c:1399
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
-#: dnsmasq.c:1357
+#: dnsmasq.c:1403
 #, fuzzy, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "feilet å laste navn fra %s: %s"
 
-#: dnsmasq.c:1361
+#: dnsmasq.c:1407
 #, fuzzy, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "feilet å laste navn fra %s: %s"
 
-#: dnsmasq.c:1365
+#: dnsmasq.c:1411
 #, fuzzy, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "feilet å lese %s: %s"
 
-#: dnsmasq.c:1369
+#: dnsmasq.c:1415
 #, fuzzy, c-format
 msgid "cannot open log %s: %s"
 msgstr "kan ikke åpne %s:%s"
 
-#: dnsmasq.c:1373
+#: dnsmasq.c:1419
 #, fuzzy, c-format
 msgid "failed to load Lua script: %s"
 msgstr "feilet å laste %s: %s"
 
-#: dnsmasq.c:1377
+#: dnsmasq.c:1423
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
-#: dnsmasq.c:1381
+#: dnsmasq.c:1427
 #, fuzzy, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "kan ikke åpne eller lage leie fil: %s"
 
-#: dnsmasq.c:1465
+#: dnsmasq.c:1511
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1469
+#: dnsmasq.c:1515
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
-#: dnsmasq.c:1473
+#: dnsmasq.c:1519
 #, fuzzy, c-format
 msgid "failed to execute %s: %s"
 msgstr "feilet å få tilgang til %s: %s"
 
-#: dnsmasq.c:1513
+#: dnsmasq.c:1559
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
+#: dnsmasq.c:1594 dnssec.c:160 dnssec.c:204
 #, fuzzy, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "feilet å lese %s: %s"
 
-#: dnsmasq.c:1560
+#: dnsmasq.c:1606
 msgid "exiting on receipt of SIGTERM"
 msgstr "avslutter etter mottak av SIGTERM"
 
-#: dnsmasq.c:1588
+#: dnsmasq.c:1634
 #, fuzzy, c-format
 msgid "failed to access %s: %s"
 msgstr "feilet å få tilgang til %s: %s"
 
-#: dnsmasq.c:1618
+#: dnsmasq.c:1664
 #, c-format
 msgid "reading %s"
 msgstr "leser %s"
 
-#: dnsmasq.c:1629
+#: dnsmasq.c:1675
 #, fuzzy, c-format
 msgid "no servers found in %s, will retry"
 msgstr "intet søke direktiv funnet i %s"
@@ -1777,27 +1886,27 @@ msgstr ""
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:471
+#: dhcp.c:473
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:526
+#: dhcp.c:530
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "DHCP område %s -- %s er ikke konsistent med nettmaske %s"
 
-#: dhcp.c:914
+#: dhcp.c:918
 #, c-format
 msgid "bad line at %s line %d"
 msgstr "dårlig linje ved %s linje %d"
 
-#: dhcp.c:957
+#: dhcp.c:961
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1100 rfc3315.c:2139
+#: dhcp.c:1105 rfc3315.c:2182
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
@@ -1843,7 +1952,7 @@ msgstr ""
 
 #: lease.c:381
 #, fuzzy, c-format
-msgid "failed to write %s: %s (retry in %us)"
+msgid "failed to write %s: %s (retry in %u s)"
 msgstr "feilet å lese %s: %s"
 
 #: lease.c:955
@@ -1851,203 +1960,203 @@ msgstr "feilet 
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
-#: rfc2131.c:372
-#, c-format
-msgid "no address range available for DHCP request %s %s"
-msgstr "ingen adresse område tilgjengelig for DHCP krav %s %s"
-
-#: rfc2131.c:373
+#: rfc2131.c:378
 msgid "with subnet selector"
 msgstr "med subnet velger"
 
-#: rfc2131.c:373
+#: rfc2131.c:383
 msgid "via"
 msgstr "via"
 
-#: rfc2131.c:385
+#: rfc2131.c:389
+#, c-format
+msgid "no address range available for DHCP request %s %s"
+msgstr "ingen adresse område tilgjengelig for DHCP krav %s %s"
+
+#: rfc2131.c:403
 #, fuzzy, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "ingen adresse område tilgjengelig for DHCP krav %s %s"
 
-#: rfc2131.c:388 rfc3315.c:319
+#: rfc2131.c:409 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
-#: rfc2131.c:499
+#: rfc2131.c:521
 #, fuzzy, c-format
 msgid "%u vendor class: %s"
 msgstr "DBus feil: %s"
 
-#: rfc2131.c:501
+#: rfc2131.c:523
 #, fuzzy, c-format
 msgid "%u user class: %s"
 msgstr "DBus feil: %s"
 
-#: rfc2131.c:535
+#: rfc2131.c:557
 msgid "disabled"
 msgstr "deaktivert"
 
-#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
-#: rfc3315.c:1097
+#: rfc2131.c:598 rfc2131.c:1087 rfc2131.c:1532 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1121
 msgid "ignored"
 msgstr "oversett"
 
-#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
+#: rfc2131.c:613 rfc2131.c:1333 rfc3315.c:867
 msgid "address in use"
 msgstr "adresse i bruk"
 
-#: rfc2131.c:605 rfc2131.c:1119
+#: rfc2131.c:627 rfc2131.c:1141
 msgid "no address available"
 msgstr "ingen adresse tilgjengelig"
 
-#: rfc2131.c:612 rfc2131.c:1273
+#: rfc2131.c:634 rfc2131.c:1295
 msgid "wrong network"
 msgstr "galt nettverk"
 
-#: rfc2131.c:627
+#: rfc2131.c:649
 msgid "no address configured"
 msgstr "ingen adresse konfigurert"
 
-#: rfc2131.c:633 rfc2131.c:1323
+#: rfc2131.c:655 rfc2131.c:1346
 msgid "no leases left"
 msgstr "ingen leier igjen"
 
-#: rfc2131.c:734 rfc3315.c:499
+#: rfc2131.c:756 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:864
+#: rfc2131.c:885
 msgid "PXE BIS not supported"
 msgstr ""
 
-#: rfc2131.c:1032 rfc3315.c:1197
+#: rfc2131.c:1054 rfc3315.c:1222
 #, fuzzy, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "deaktiverer DHCP statisk adresse %s"
 
-#: rfc2131.c:1053
+#: rfc2131.c:1075
 msgid "unknown lease"
 msgstr "ukjent leie"
 
-#: rfc2131.c:1088
+#: rfc2131.c:1110
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1098
+#: rfc2131.c:1120
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1101
+#: rfc2131.c:1123
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1117 rfc2131.c:1316
+#: rfc2131.c:1139 rfc2131.c:1339
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1209
+#: rfc2131.c:1231
 msgid "wrong server-ID"
 msgstr ""
 
-#: rfc2131.c:1228
+#: rfc2131.c:1250
 msgid "wrong address"
 msgstr "gal adresse"
 
-#: rfc2131.c:1246 rfc3315.c:961
+#: rfc2131.c:1268 rfc3315.c:975
 msgid "lease not found"
 msgstr "leie ikke funnet"
 
-#: rfc2131.c:1281
+#: rfc2131.c:1303
 msgid "address not available"
 msgstr "adresse ikke tilgjengelig"
 
-#: rfc2131.c:1292
+#: rfc2131.c:1314
 msgid "static lease available"
 msgstr "statisk leie tilgjengelig"
 
-#: rfc2131.c:1296
+#: rfc2131.c:1318
 msgid "address reserved"
 msgstr "adresse reservert"
 
-#: rfc2131.c:1304
+#: rfc2131.c:1327
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1845
+#: rfc2131.c:1866
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
-#: rfc2131.c:1854
+#: rfc2131.c:1875
 #, fuzzy, c-format
 msgid "%u server name: %s"
 msgstr "DBus feil: %s"
 
-#: rfc2131.c:1862
+#: rfc2131.c:1885
 #, fuzzy, c-format
 msgid "%u next server: %s"
 msgstr "DBus feil: %s"
 
-#: rfc2131.c:1865
+#: rfc2131.c:1889
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1928
+#: rfc2131.c:1952
 #, fuzzy, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "kan ikke sende DHCP opsjon %d: ikke mer plass i pakken"
 
-#: rfc2131.c:2219
+#: rfc2131.c:2262
 msgid "PXE menu too large"
 msgstr ""
 
-#: rfc2131.c:2358 rfc3315.c:1470
+#: rfc2131.c:2425 rfc3315.c:1511
 #, fuzzy, c-format
 msgid "%u requested options: %s"
 msgstr "kompilerings opsjoner: %s"
 
-#: rfc2131.c:2675
+#: rfc2131.c:2742
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2738
+#: rfc2131.c:2805
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:76
+#: netlink.c:93
 #, fuzzy, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "kan ikke binde netlink socket: %s"
 
-#: netlink.c:352
+#: netlink.c:377
 #, fuzzy, c-format
 msgid "netlink returns error: %s"
 msgstr "DBus feil: %s"
 
-#: dbus.c:438
+#: dbus.c:434
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:443
+#: dbus.c:439
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:717
+#: dbus.c:713
 msgid "setting upstream servers from DBus"
 msgstr "setter oppstrøms tjener fra DBus"
 
-#: dbus.c:764
+#: dbus.c:760
 msgid "could not register a DBus message handler"
 msgstr "kunne ikke registrere en DBus meldingshåndterer"
 
@@ -2074,31 +2183,36 @@ msgstr ""
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:347
+#: tftp.c:349
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:363
+#: tftp.c:365
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
-#: tftp.c:510
+#: tftp.c:512
 #, fuzzy, c-format
 msgid "file %s not found"
 msgstr "leie ikke funnet"
 
-#: tftp.c:628
+#: tftp.c:602
+#, c-format
+msgid "ignoring packet from %s (TID mismatch)"
+msgstr ""
+
+#: tftp.c:646
 #, fuzzy, c-format
 msgid "failed sending %s to %s"
 msgstr "feilet å lese %s: %s"
 
-#: tftp.c:628
+#: tftp.c:646
 #, c-format
 msgid "sent %s to %s"
 msgstr ""
 
-#: tftp.c:678
+#: tftp.c:696
 #, c-format
 msgid "error %d %s received from %s"
 msgstr ""
@@ -2113,7 +2227,7 @@ msgstr ""
 msgid "log failed: %s"
 msgstr ""
 
-#: log.c:471
+#: log.c:477
 msgid "FAILED to start up"
 msgstr "FEILET å starte opp"
 
@@ -2167,11 +2281,11 @@ msgstr "ingen tilknytning (interface) med adresse %s"
 msgid "address unavailable"
 msgstr "adresse ikke tilgjengelig"
 
-#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1272
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913 rfc3315.c:1047
 #, fuzzy
 msgid "no addresses available"
 msgstr "ingen adresse tilgjengelig"
@@ -2180,116 +2294,116 @@ msgstr "ingen adresse tilgjengelig"
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
+#: rfc3315.c:979 rfc3315.c:1180 rfc3315.c:1261
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1002
+#: rfc3315.c:1016
 msgid "deprecated"
 msgstr ""
 
-#: rfc3315.c:1007
+#: rfc3315.c:1023
 #, fuzzy
 msgid "address invalid"
 msgstr "adresse i bruk"
 
-#: rfc3315.c:1057 rfc3315.c:1059
+#: rfc3315.c:1081 rfc3315.c:1083
 msgid "confirm failed"
 msgstr ""
 
-#: rfc3315.c:1074
+#: rfc3315.c:1098
 #, fuzzy
 msgid "all addresses still on link"
 msgstr "dårlig adresse ved %s linje %d"
 
-#: rfc3315.c:1165
+#: rfc3315.c:1189
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2130
+#: rfc3315.c:2173
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
-#: dhcp-common.c:145
+#: dhcp-common.c:154
 #, c-format
 msgid "Ignoring duplicate dhcp-option %d"
 msgstr ""
 
-#: dhcp-common.c:222
+#: dhcp-common.c:231
 #, c-format
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:444
+#: dhcp-common.c:451
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
-#: dhcp-common.c:478
+#: dhcp-common.c:485
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "dubliserte IP adresser i %s (%s) i dhcp-config direktiv"
 
-#: dhcp-common.c:542
+#: dhcp-common.c:549
 #, fuzzy, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "feilet å sette SO_REUSEADDR på DHCP socket: %s"
 
-#: dhcp-common.c:665
+#: dhcp-common.c:672
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:676
+#: dhcp-common.c:683
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:873
+#: dhcp-common.c:880
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:876
+#: dhcp-common.c:883
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:918
+#: dhcp-common.c:925
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
-#: dhcp-common.c:920
+#: dhcp-common.c:927
 #, fuzzy, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "DHCP, statisk leie kun på %.0s%s, leie tid %s"
 
-#: dhcp-common.c:922
+#: dhcp-common.c:929
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
-#: dhcp-common.c:923
+#: dhcp-common.c:930
 #, fuzzy, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "DHCP, IP område %s -- %s, leie tid %s"
 
-#: dhcp-common.c:936
+#: dhcp-common.c:943
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:939
+#: dhcp-common.c:946
 #, fuzzy, c-format
 msgid "router advertisement on %s%s"
 msgstr "DHCP, statisk leie kun på %.0s%s, leie tid %s"
 
-#: dhcp-common.c:950
+#: dhcp-common.c:957
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:952
+#: dhcp-common.c:959
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2299,31 +2413,119 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "kan ikke lage DHCP socket: %s"
 
-#: auth.c:439
+#: auth.c:464
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
 
-#: ipset.c:95
-#, fuzzy, c-format
-msgid "failed to find kernel version: %s"
-msgstr "feilet å binde DHCP tjener socket: %s"
-
-#: ipset.c:114
+#: ipset.c:99
 #, fuzzy, c-format
 msgid "failed to create IPset control socket: %s"
 msgstr "feilet å lage lytte socket: %s"
 
-#: ipset.c:226
+#: ipset.c:211
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "feilet å lese %s: %s"
 
+#: pattern.c:29
+#, c-format
+msgid "[pattern.c:%d] Assertion failure: %s"
+msgstr ""
+
+#: pattern.c:142
+#, c-format
+msgid "Invalid DNS name: Invalid character %c."
+msgstr ""
+
+#: pattern.c:151
+msgid "Invalid DNS name: Empty label."
+msgstr ""
+
+#: pattern.c:156
+msgid "Invalid DNS name: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:170
+msgid "Invalid DNS name: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:176
+#, c-format
+msgid "Invalid DNS name: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:184
+#, c-format
+msgid "Invalid DNS name: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:189
+msgid "Invalid DNS name: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:199
+msgid "Invalid DNS name: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:204
+#, c-format
+msgid "DNS name has invalid length (%zu)."
+msgstr ""
+
+#: pattern.c:258
+#, c-format
+msgid "Invalid DNS name pattern: Invalid character %c."
+msgstr ""
+
+#: pattern.c:267
+msgid "Invalid DNS name pattern: Empty label."
+msgstr ""
+
+#: pattern.c:272
+msgid "Invalid DNS name pattern: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:285
+msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+msgstr ""
+
+#: pattern.c:295
+msgid "Invalid DNS name pattern: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:301
+#, c-format
+msgid "Invalid DNS name pattern: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:309
+#, c-format
+msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:314
+msgid "Invalid DNS name pattern: Wildcard within final two labels."
+msgstr ""
+
+#: pattern.c:319
+msgid "Invalid DNS name pattern: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:329
+msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:334
+#, c-format
+msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
+msgstr ""
+
 #: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: dnssec.c:902
+#: dnssec.c:1014
 #, c-format
 msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
 msgstr ""
@@ -2355,7 +2557,7 @@ msgstr ""
 
 #: tables.c:101
 #, fuzzy, c-format
-msgid "IPset: error:%s"
+msgid "IPset: error: %s"
 msgstr "DBus feil: %s"
 
 #: tables.c:108
@@ -2417,56 +2619,54 @@ msgstr "kan ikke lese %s: %s"
 msgid "bad header in %s"
 msgstr "adresse i bruk"
 
-#: dump.c:201
+#: dump.c:205
 #, fuzzy
 msgid "failed to write packet dump"
 msgstr "feilet å lytte på socket: %s"
 
-#: dump.c:203
+#: dump.c:207
 #, c-format
 msgid "dumping UDP packet %u mask 0x%04x"
 msgstr ""
 
-#: ubus.c:52
+#: ubus.c:79
 #, c-format
 msgid "UBus subscription callback: %s subscriber(s)"
 msgstr ""
 
-#: ubus.c:73
+#: ubus.c:99
 #, fuzzy, c-format
 msgid "Cannot reconnect to UBus: %s"
 msgstr "kan ikke åpne %s:%s"
 
-#: ubus.c:89
-msgid "Cannot initialize UBus: connection failed"
-msgstr ""
-
-#: ubus.c:102
-#, fuzzy, c-format
-msgid "Cannot add object to UBus: %s"
-msgstr "kan ikke åpne %s:%s"
-
-#: ubus.c:112
-#, fuzzy
-msgid "Connected to system UBus"
-msgstr "tilkoblet til system DBus"
-
-#: ubus.c:122
+#: ubus.c:135
 msgid "Cannot set UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:142
+#: ubus.c:155
 msgid "Cannot poll UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:155
+#: ubus.c:168
 msgid "Disconnecting from UBus"
 msgstr ""
 
-#: ubus.c:199
-#, fuzzy, c-format
-msgid "Failed to send UBus event: %s"
-msgstr "feilet å lytte på socket: %s"
+#: ubus.c:179 ubus.c:326
+#, c-format
+msgid "UBus command failed: %d (%s)"
+msgstr ""
+
+#: hash-questions.c:40
+msgid "Failed to create SHA-256 hash object"
+msgstr ""
+
+#, fuzzy
+#~ msgid "Cannot add object to UBus: %s"
+#~ msgstr "kan ikke åpne %s:%s"
+
+#, fuzzy
+#~ msgid "Failed to send UBus event: %s"
+#~ msgstr "feilet å lytte på socket: %s"
 
 #~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
 #~ msgstr "forsøk på å sette en IPv6 tjener adresse via DBus - ingen IPv6 støtte"
index a947f03..29b9165 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -21,778 +21,812 @@ msgstr ""
 "X-Generator: Poedit 1.8.7\n"
 "X-Language: pl_PL\n"
 
-#: cache.c:559
+#: cache.c:572
 msgid "Internal error in cache."
 msgstr "Wewnętrzny błąd w pamięci podręcznej."
 
-#: cache.c:1081
+#: cache.c:1094
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr "nie potrafię wczytać nazw z %s: %s"
 
-#: cache.c:1103 dhcp.c:927
+#: cache.c:1116 dhcp.c:931
 #, c-format
 msgid "bad address at %s line %d"
 msgstr "błędny adres w pliku %s, w linii %d"
 
-#: cache.c:1156 dhcp.c:943
+#: cache.c:1169 dhcp.c:947
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "błędna nazwa w pliku %s, w linii %d"
 
-#: cache.c:1167 dhcp.c:1018
+#: cache.c:1180 dhcp.c:1022
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "wczytałem %s - %d adresów"
 
-#: cache.c:1283
+#: cache.c:1296
 msgid "cleared cache"
 msgstr "wyczyszczono pamięć podręczną"
 
-#: cache.c:1345
+#: cache.c:1358
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr "Nie znalazłem adresu IPv4 komputera %s"
 
-#: cache.c:1391
+#: cache.c:1404
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr "%s to nazwa CNAME, nie przypisuję jej dzierżawie DHCP %s"
 
-#: cache.c:1415
+#: cache.c:1428
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "nazwa %s nie została nadana dzierżawie DHCP %s, ponieważ nazwa istnieje w %s i ma już adres %s"
 
-#: cache.c:1663
+#: cache.c:1674
 #, c-format
 msgid "time %lu"
 msgstr "czas %lu"
 
-#: cache.c:1664
+#: cache.c:1675
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "wielkość pamięci podręcznej: %d; %d z %d miejsc aktualnych wpisów użyto ponownie."
 
-#: cache.c:1666
+#: cache.c:1677
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr "%u zapytań przesłanych dalej, %u odpowiedzi udzielonych samodzielnie"
 
-#: cache.c:1669
+#: cache.c:1680
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr "zapytań do stref autorytatywnych %u"
 
-#: cache.c:1694
+#: cache.c:1702
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr "serwer %s#%d: %u zapytań wysłanych, %u ponowionych lub nieudanych"
 
-#: util.c:47
+#: util.c:51
 #, c-format
 msgid "failed to seed the random number generator: %s"
 msgstr "brak możliwości użycia generatora liczb losowych: %s"
 
-#: util.c:224
+#: util.c:228
 msgid "failed to allocate memory"
 msgstr "nie udało się przydzielić pamięci"
 
-#: util.c:281 option.c:641
+#: util.c:285 option.c:665
 msgid "could not get memory"
 msgstr "nie można dostać pamięci"
 
-#: util.c:302
+#: util.c:306
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr "błąd podczas próby utworzenia potoku: %s"
 
-#: util.c:310
+#: util.c:314
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr "niemożliwość przydzielenia %d bajtów pamięci"
 
-#: util.c:506
+#: util.c:520
 #, c-format
 msgid "infinite"
 msgstr "nieskończona"
 
-#: option.c:358
+#: util.c:808
+#, c-format
+msgid "failed to find kernel version: %s"
+msgstr "niezgodna wersja jądra: %s"
+
+#: option.c:372
 msgid "Specify local address(es) to listen on."
 msgstr "Wskazanie adresów, na których należy nasłuchiwać."
 
-#: option.c:359
+#: option.c:373
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Zwracanie adresu IP dla wszystkich hostów we wskazanych domenach."
 
-#: option.c:360
+#: option.c:374
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Wyłączenie przekazywania zapytań odwrotnych dla prywatnych zakresów IP."
 
-#: option.c:361
+#: option.c:375
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Traktowanie adresu IP jako NXDOMAIN (unieważnia ,,Verisign wildcard'')."
 
-#: option.c:362
+#: option.c:376
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Wskazanie wielkości pamięci podręcznej (domyślnie: %s miejsc)."
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Wskazanie pliku konfiguracyjnego (domyślnie: %s)."
 
-#: option.c:364
+#: option.c:378
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "NIE twórz procesu potomnego w tle: działanie w trybie debugowania."
 
-#: option.c:365
+#: option.c:379
 msgid "Do NOT forward queries with no domain part."
 msgstr "Wyłączenie przekazywania zapytań bez podanej części domenowej."
 
-#: option.c:366
+#: option.c:380
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Zwracanie samowskazującego rekordu MX dla lokalnych hostów."
 
-#: option.c:367
+#: option.c:381
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Rozwijanie prostych nazw z /etc/hosts przyrostkiem domenowym."
 
-#: option.c:368
+#: option.c:382
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "Wyłączenie przekazywania pozornych zapytań DNS z komputerów działających pod Windows."
 
-#: option.c:369
+#: option.c:383
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Włączenie serwera DHCP dla wskazanego zakresu adresów."
 
-#: option.c:370
+#: option.c:384
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Po uruchomieniu zmiana grupy procesu na podaną (domyślnie: %s)."
 
-#: option.c:371
+#: option.c:385
 msgid "Set address or hostname for a specified machine."
 msgstr "Ustawienie adresu lub nazwy dla wskazanego komputera."
 
-#: option.c:372
+#: option.c:386
 msgid "Read DHCP host specs from file."
 msgstr "Wskazanie pliku z wartościami 'dhcp-host='."
 
-#: option.c:373
+#: option.c:387
 msgid "Read DHCP option specs from file."
 msgstr "Wskazanie pliku z wartościami 'dhcp-option='."
 
-#: option.c:374
+#: option.c:388
 msgid "Read DHCP host specs from a directory."
 msgstr "Odczyt specyfikacji hostów dla DHCP z katalogu."
 
-#: option.c:375
+#: option.c:389
 msgid "Read DHCP options from a directory."
 msgstr "Odczyt opcji DHCP z katalogu."
 
-#: option.c:376
+#: option.c:390
 msgid "Evaluate conditional tag expression."
 msgstr "Warunkowe ustawianie znaczników."
 
-#: option.c:377
+#: option.c:391
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "NIE wczytywanie pliku %s."
 
-#: option.c:378
+#: option.c:392
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Wskazanie dodatkowego pliku 'hosts' oprócz %s."
 
-#: option.c:379
+#: option.c:393
 msgid "Read hosts files from a directory."
 msgstr "Odczyt pliku hostów z katalogu."
 
-#: option.c:380
+#: option.c:394
 msgid "Specify interface(s) to listen on."
 msgstr "Interfejsy, na których nasłuchiwać."
 
-#: option.c:381
+#: option.c:395
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Interfejsy, na których NIE nasłuchiwać."
 
-#: option.c:382
+#: option.c:396
 msgid "Map DHCP user class to tag."
 msgstr "Przyporządkowanie znacznika w zależności od klasy użytkownika DHCP."
 
-#: option.c:383
+#: option.c:397
 msgid "Map RFC3046 circuit-id to tag."
 msgstr "Przyporządkowanie znacznika w zależności od numeru obwodu (w rozumieniu RFC3046)."
 
-#: option.c:384
+#: option.c:398
 msgid "Map RFC3046 remote-id to tag."
 msgstr "Przyporządkowanie znacznika w zależności od numeru agenta (w rozumieniu RFC3046)."
 
-#: option.c:385
+#: option.c:399
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr "Przyporządkowanie znacznika w zależności od numeru subskrybenta (w rozumieniu RFC3993)."
 
-#: option.c:386
+#: option.c:400
+msgid "Specify vendor class to match for PXE requests."
+msgstr ""
+
+#: option.c:401
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Wyłączenie DHCP dla hostów z określonym znacznikiem."
 
-#: option.c:387
+#: option.c:402
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Wymuszenie odpowiedzi w trybie rozgłoszeniowym dla hostów z określonym znacznikiem."
 
-#: option.c:388
+#: option.c:403
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "NIE twórz procesu potomnego w tle i NIE włączaj trybu debugowania."
 
-#: option.c:389
+#: option.c:404
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Zakładanie, że jesteśmy jedynym serwerem DHCP w sieci lokalnej."
 
-#: option.c:390
+#: option.c:405
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Ścieżka przechowywania pliku dzierżaw DHCP (domyślnie: %s)."
 
-#: option.c:391
+#: option.c:406
 msgid "Return MX records for local hosts."
 msgstr "Włączenie zwracania rekordu MX dla hostów lokalnych."
 
-#: option.c:392
+#: option.c:407
 msgid "Specify an MX record."
 msgstr "Specyfikacja rekordu MX."
 
-#: option.c:393
+#: option.c:408
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Określenie opcji BOOTP serwera DHCP."
 
-#: option.c:394
+#: option.c:409
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "Wyłączenie obserwowania pliku %s; ponowne odczytywanie tylko po odebraniu sygnału SIGHUP."
 
-#: option.c:395
+#: option.c:410
 msgid "Do NOT cache failed search results."
 msgstr "Wyłączenie przechowywania w pamięci podręcznej wyników nieudanych wyszukiwań."
 
-#: option.c:396
+#: option.c:411
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Odpytywanie serwerów nazw w kolejności ich wystąpienia w %s."
 
-#: option.c:397
+#: option.c:412
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Specyfikacja opcji wysyłanej do klientów DHCP."
 
-#: option.c:398
+#: option.c:413
 msgid "DHCP option sent even if the client does not request it."
 msgstr "Opcja DHCP wysyłana nawet jeżeli klient o nią nie prosi."
 
-#: option.c:399
+#: option.c:414
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Wskazanie portu do nasłuchiwania zapytań DNS (domyślnie: 53)."
 
-#: option.c:400
+#: option.c:415
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Maksymalna obsługiwana wielkość pakietu EDNS.0 (domyślnie: %s)."
 
-#: option.c:401
+#: option.c:416
 msgid "Log DNS queries."
 msgstr "Włączenie spisywania zapytań DNS do logu."
 
-#: option.c:402
+#: option.c:417
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Wymuszenie użycia wskazanego portu UDP do odpytywania nadrzędnych serwerów DNS i odbierania od nich odpowiedzi."
 
-#: option.c:403
+#: option.c:418
 msgid "Do NOT read resolv.conf."
 msgstr "Wyłączenie czytania pliku resolv.conf."
 
-#: option.c:404
+#: option.c:419
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Wskazanie położenia pliku resolv.conf (domyślnie: %s)."
 
-#: option.c:405
+#: option.c:420
 msgid "Specify path to file with server= options"
 msgstr "Wskazanie położenia pliku z opcjami server="
 
-#: option.c:406
+#: option.c:421
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Wskazywanie adresów serwerów nazw, opcjonalnie z przypisaniem do domeny."
 
-#: option.c:407
+#: option.c:422
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Wskazanie serwerów nazw do odwrotnej translacji adresów."
 
-#: option.c:408
+#: option.c:423
 msgid "Never forward queries to specified domains."
 msgstr "Wyłączenie przekazywania zapytań do wskazanych domen."
 
-#: option.c:409
+#: option.c:424
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Wskazanie domeny dla serwera DHCP."
 
-#: option.c:410
+#: option.c:425
 msgid "Specify default target in an MX record."
 msgstr "Określenie domyślnego celu w rekordzie MX."
 
-#: option.c:411
+#: option.c:426
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Określenie (w sekundach) czasu ważności odpowiedzi udzielonych na podstawie /etc/hosts (domyślnie 0)."
 
-#: option.c:412
+#: option.c:427
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Określenie (w sekundach) czasu ważności negatywnych odpowiedzi."
 
-#: option.c:413
+#: option.c:428
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Ograniczenie maksymalnego czasu ważności odpowiedzi (TTL) podawanego klientom [w sekundach]."
 
-#: option.c:414
+#: option.c:429
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Określenie górnej granicy czasu ważności dla wpisów w pamięci podręcznej."
 
-#: option.c:415
+#: option.c:430
 msgid "Specify time-to-live floor for cache."
 msgstr "Określenie dolnej granicy czasu ważności dla wpisów w pamięci podręcznej."
 
-#: option.c:416
+#: option.c:431
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Zmiana użytkownika procesu na wskazanego (po uruchomieniu, domyślnie: %s)."
 
-#: option.c:417
+#: option.c:432
 msgid "Map DHCP vendor class to tag."
 msgstr "Przyporządkowanie znacznika w zależności od typu klienta DHCP."
 
-#: option.c:418
+#: option.c:433
 msgid "Display dnsmasq version and copyright information."
 msgstr "Wydrukowanie informacji o programie i ochronie praw autorskich."
 
-#: option.c:419
+#: option.c:434
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Tłumaczenie adresów IPv4 z serwerów nadrzędnych."
 
-#: option.c:420
+#: option.c:435
 msgid "Specify a SRV record."
 msgstr "Określenie rekordu SRV."
 
-#: option.c:421
+#: option.c:436
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr "Wyświetla ten komunikat. Chcąc przejrzeć listę dostępnych opcji DHCP użyj '--help dhcp' lub '--help dhcp6' ."
 
-#: option.c:422
+#: option.c:437
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Określenie ścieżki do pliku PID (domyślnie: %s)."
 
-#: option.c:423
+#: option.c:438
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Maksymalna liczba dzierżaw DHCP (domyślnie: %s)."
 
-#: option.c:424
+#: option.c:439
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Uzależnienie odpowiedzi DNS od interfejsu, na którym odebrano zapytanie (wygodne dla serwerów kilku podsieci z różnymi adresami w /etc/hosts)."
 
-#: option.c:425
+#: option.c:440
 msgid "Specify TXT DNS record."
 msgstr "Specyfikacja rekordu DNS TXT."
 
-#: option.c:426
+#: option.c:441
 msgid "Specify PTR DNS record."
 msgstr "Specyfikacja rekordu DNS PTR."
 
-#: option.c:427
+#: option.c:442
 msgid "Give DNS name to IPv4 address of interface."
 msgstr "Zwraca nazwę domenową powiązaną z adresem interfejsu sieciowego."
 
-#: option.c:428
+#: option.c:443
 msgid "Bind only to interfaces in use."
 msgstr "Nasłuchiwanie tylko na wykorzystywanych interfejsach (umożliwia uruchomienie osobnych serwerów dla różnych kart)."
 
-#: option.c:429
+#: option.c:444
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Wczytanie przyporządkowań adresów z %s."
 
-#: option.c:430
+#: option.c:445
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Włączenie używania interfejsu DBus do informowania o zmianach konfiguracji."
 
-#: option.c:431
+#: option.c:446
 msgid "Enable the UBus interface."
 msgstr ""
 
-#: option.c:432
+#: option.c:447
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "Uruchomienie na wskazanym interfejsie tylko DNS-a, bez usług DHCP i TFTP."
 
-#: option.c:433
+#: option.c:448
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Włączenie dynamicznego przydzielania adresów dla klientów BOOTP."
 
-#: option.c:434
+#: option.c:449
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Przyporządkowanie znacznika w zależności od adresu MAC (można używać uogólnień: *)."
 
-#: option.c:435
+#: option.c:450
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr "Traktowanie żądań DHCP odebranych na interfejsach alias, ..., jako odebranych na iface."
 
-#: option.c:436
+#: option.c:451
 msgid "Specify extra networks sharing a broadcast domain for DHCP"
 msgstr ""
 
-#: option.c:437
+#: option.c:452
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr "Pominięcie sprawdzania za pomocą ICMP niezajętości adresu przed jego wydzierżawieniem."
 
-#: option.c:438
+#: option.c:453
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr "Skrypt powłoki uruchamiany po przyznaniu lub zwolnieniu adresu."
 
-#: option.c:439
+#: option.c:454
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr "Skrypt Lua uruchamiany po przyznaniu lub zwolnieniu adresu."
 
-#: option.c:440
+#: option.c:455
 msgid "Run lease-change scripts as this user."
 msgstr "Wskazanie użytkownika z którego uprawnieniami będą uruchamiane skrypty."
 
-#: option.c:441
+#: option.c:456
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr "Wywoływanie dhcp-script w reakcji na zmiany w tablicy ARP."
 
-#: option.c:442
+#: option.c:457
 msgid "Read configuration from all the files in this directory."
 msgstr "Wczytanie wszystkich plików ze wskazanego katalogu jako konfiguracyjnych."
 
-#: option.c:443
+#: option.c:458
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Wskazanie kanału syslog-a do którego mają trafiać komunikaty (domyślnie: DAEMON)"
 
-#: option.c:444
+#: option.c:459
 msgid "Do not use leasefile."
 msgstr "Nieużywanie bazy dzierżaw."
 
-#: option.c:445
+#: option.c:460
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Maksymalna liczba jednocześnie obsługiwanych zapytań DNS (domyślnie: %s)"
 
-#: option.c:446
+#: option.c:461
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr "Czyszczenie pamięci podręcznej serwera nazw w przypadku ponownego odczytu %s."
 
-#: option.c:447
+#: option.c:462
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr "Nie zwracanie uwagi na nazwę podawaną przez klienta w przypadku dopasowania wszystkich wymienionych znaczników."
 
-#: option.c:448
+#: option.c:463
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr "Wyłączenie oszczędzania miejsca w pakiecie DHCP przez przesuwanie pól servername i filename do opcji DHCP. Wymusza prostszy tryb budowy pakietu rozwiązując problemy z nieprzystosowanymi klientami DHCP."
 
-#: option.c:449
+#: option.c:464
 msgid "Enable integrated read-only TFTP server."
 msgstr "Włączenie wbudowanego serwera TFTP (tylko do wysyłania)."
 
-#: option.c:450
+#: option.c:465
 msgid "Export files by TFTP only from the specified subtree."
 msgstr "Ograniczenie działania serwera TFTP do wskazanego katalogu i podkatalogów. Nazwy z .. są odrzucane, / odnosi się do wskazanego katalogu."
 
-#: option.c:451
+#: option.c:466
 #, fuzzy
 msgid "Add client IP or hardware address to tftp-root."
 msgstr "Doklejanie adresu IP klienta do głównego katalogu TFTP. Jeżeli wynikowy katalog nie istnieje, nadal wykorzystuje się tftp-root."
 
-#: option.c:452
+#: option.c:467
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr "Ograniczenie dostępu do plików przez TFTP do tych, których właścicielem jest użytkownik uruchamiający dnsmasq-a."
 
-#: option.c:453
+#: option.c:468
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr "Nieprzerywanie działania serwisu mimo braku dostępu do katalogów TFTP."
 
-#: option.c:454
+#: option.c:469
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Maksymalna liczba jednocześnie obsługiwanych połączeń TFTP (domyślnie %s)."
 
-#: option.c:455
+#: option.c:470
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Ograniczenie MTU w komunikacji TFTP."
 
-#: option.c:456
+#: option.c:471
 msgid "Disable the TFTP blocksize extension."
 msgstr "Wyłączenie możliwości negocjowania wielkości bloku dla przesyłów przez TFTP."
 
-#: option.c:457
+#: option.c:472
 msgid "Convert TFTP filenames to lowercase"
 msgstr "Konwertowanie nazw plików żądanych przez TFTP do małych liter"
 
-#: option.c:458
+#: option.c:473
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr "Wskazanie zakresu portów do użytku TFTP."
 
-#: option.c:459
+#: option.c:474
 msgid "Use only one port for TFTP server."
 msgstr ""
 
-#: option.c:460
+#: option.c:475
 msgid "Extra logging for DHCP."
 msgstr "Włączenie spisywania w logu operacji DHCP."
 
-#: option.c:461
+#: option.c:476
 msgid "Enable async. logging; optionally set queue length."
 msgstr "Włączenie asynchronicznego zapisywania do logu z ewentualnym wskazaniem długości kolejki."
 
-#: option.c:462
+#: option.c:477
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr "Odfiltrowywanie adresów wskazujących na komputery w sieciach wewnętrznych spośród odpowiedzi od zewnętrznych serwerów DNS."
 
-#: option.c:463
+#: option.c:478
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr "Zezwolenie na przekazywanie odpowiedzi w klasie 127.0.0.0/8. Dla serwerów RBL."
 
-#: option.c:464
+#: option.c:479
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr "Dezaktywacja zabezpieczenia przed atakami DNS-rebind dla wskazanych domen."
 
-#: option.c:465
+#: option.c:480
 msgid "Always perform DNS queries to all servers."
 msgstr "Jednoczesne odpytywanie wszystkich serwerów nadrzędnych; klientowi przekazywana jest pierwsza odpowiedź."
 
-#: option.c:466
+#: option.c:481
 msgid "Set tag if client includes matching option in request."
 msgstr "Ustawienie znacznika jeżeli w żądaniu DHCP pojawi się wskazana opcja, ewentualnie o konkretnej wartości."
 
-#: option.c:467
+#: option.c:482
 #, fuzzy
 msgid "Set tag if client provides given name."
 msgstr "Ustawienie znacznika jeżeli w żądaniu DHCP pojawi się wskazana opcja, ewentualnie o konkretnej wartości."
 
-#: option.c:468
+#: option.c:483
 msgid "Use alternative ports for DHCP."
 msgstr "Użycie alternatywnych portów dla usługi DHCP."
 
-#: option.c:469
+#: option.c:484
 msgid "Specify NAPTR DNS record."
 msgstr "Specyfikacja rekordu DNS NAPTR."
 
-#: option.c:470
+#: option.c:485
 msgid "Specify lowest port available for DNS query transmission."
 msgstr "Ustawienie dolnej granicy numerów portów do przesyłania zapytań DNS."
 
-#: option.c:471
+#: option.c:486
 msgid "Specify highest port available for DNS query transmission."
 msgstr "Ograniczenie najwyższego numeru portu dla transmisji zapytań DNS."
 
-#: option.c:472
+#: option.c:487
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr "Przechowywanie w serwerze DNS dnsmasq-a tylko w pełni kwalifikowanych nazw zgłaszanych przez klientów DHCP."
 
-#: option.c:473
+#: option.c:488
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr "Generowanie nazw na podstawie MAC-adresów dla klientów bez nazwy."
 
-#: option.c:474
+#: option.c:489
 msgid "Use these DHCP relays as full proxies."
 msgstr "Traktowanie wskazanych serwerów pośredniczących DHCP jako działających w trybie \"pełnomocnika\" (full-proxy)."
 
-#: option.c:475
+#: option.c:490
 msgid "Relay DHCP requests to a remote server"
 msgstr "Przekazywanie żądań DHCP do zdalnego serwera"
 
-#: option.c:476
+#: option.c:491
 msgid "Specify alias name for LOCAL DNS name."
 msgstr "Wskazanie synonimu nazwy komputera lokalnego - znanego z /etc/hosts albo z DHCP."
 
-#: option.c:477
+#: option.c:492
 msgid "Prompt to send to PXE clients."
 msgstr "Zgłoszenie wysyłane klientom PXE."
 
-#: option.c:478
+#: option.c:493
 msgid "Boot service for PXE menu."
 msgstr "Składnik menu PXE (--> man)."
 
-#: option.c:479
+#: option.c:494
 msgid "Check configuration syntax."
 msgstr "Sprawdzenie składni."
 
-#: option.c:480
+#: option.c:495
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr "Przekazywanie MAC-adresu komputera pytającego w ruchu wychodzącym DNS."
 
-#: option.c:481
+#: option.c:496
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr "Zamieszczanie wskazanego adresu podsieci w przekazywanych zapytaniach DNS."
 
-#: option.c:482
+#: option.c:497
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Zamieszczanie identyfikacji pytającego w przekazywanych zapytaniach DNS."
 
-#: option.c:483
+#: option.c:498
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Przekazywanie wyników weryfikacji DNSSEC z serwerów nadrzędnych."
 
-#: option.c:484
+#: option.c:499
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr "Zmiana sposobu przydzielania adresów IP na sekwencyjny."
 
-#: option.c:485
+#: option.c:500
 #, fuzzy
 msgid "Ignore client identifier option sent by DHCP clients."
 msgstr "Nie zwracanie uwagi na nazwę podawaną przez klienta w przypadku dopasowania wszystkich wymienionych znaczników."
 
-#: option.c:486
+#: option.c:501
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr "Zachowanie znacznika połączenia z odebranego zapytania DNS w ruchu zewnętrznym."
 
-#: option.c:487
+#: option.c:502
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr "Zezwolenie klientom DHCP na uaktualnianie DDNS-ów."
 
-#: option.c:488
+#: option.c:503
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr "Załączenie anonsowania (RA) na interfejsach serwujących DHCPv6"
 
-#: option.c:489
+#: option.c:504
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr "Określenie DHCPv6 DUID"
 
-#: option.c:490
+#: option.c:505
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Określenie rekordów A/AAAA i PTR"
 
-#: option.c:491
+#: option.c:506
+msgid "Specify host record in interface subnet"
+msgstr ""
+
+#: option.c:507
 msgid "Specify certification authority authorization record"
 msgstr ""
 
-#: option.c:492
+#: option.c:508
 msgid "Specify arbitrary DNS resource record"
 msgstr "Określenie rekordu TXT"
 
-#: option.c:493
+#: option.c:509
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "Dynamiczne podpinanie do interfejsów sieciowych"
 
-#: option.c:494
+#: option.c:510
 msgid "Export local names to global DNS"
 msgstr "Eksportowanie lokalnych nazw hostów do globalnego DNS-a"
 
-#: option.c:495
+#: option.c:511
 msgid "Domain to export to global DNS"
 msgstr "Domena pod którą będą eksportowane lokalne nazwy"
 
-#: option.c:496
+#: option.c:512
 msgid "Set TTL for authoritative replies"
 msgstr "Określenie TTL dla odpowiedzi autorytatywnych"
 
-#: option.c:497
+#: option.c:513
 #, fuzzy
 msgid "Set authoritative zone information"
 msgstr "Określenie danych strefy autorytatywnej (SOA)"
 
-#: option.c:498
+#: option.c:514
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr "Pomocnicze serwery autorytatywne dla forwardowanych domen"
 
-#: option.c:499
+#: option.c:515
 msgid "Peers which are allowed to do zone transfer"
 msgstr "Wskazanie serwerów uprawnionych do transferu stref"
 
-#: option.c:500
+#: option.c:516
 msgid "Specify ipsets to which matching domains should be added"
 msgstr "Wyszczególnienie ipset-ów, do których będą dopisywane adresy IP leżące we wskazanych domenach"
 
-#: option.c:501
+#: option.c:517
+msgid "Enable filtering of DNS queries with connection-track marks."
+msgstr ""
+
+#: option.c:518
+msgid "Set allowed DNS patterns for a connection-track mark."
+msgstr ""
+
+#: option.c:519
 msgid "Specify a domain and address range for synthesised names"
 msgstr "Wskazanie domeny i zakresu adresów dla generowanych nazw"
 
-#: option.c:502
+#: option.c:520
 msgid "Activate DNSSEC validation"
 msgstr "Uaktywnienie walidacji DNSSEC"
 
-#: option.c:503
+#: option.c:521
 msgid "Specify trust anchor key digest."
 msgstr "Wskazanie punktu zaufania dla uwierzytelniania DNSSEC."
 
-#: option.c:504
+#: option.c:522
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr "Akceptowanie nieuwiarygodnionych odpowiedzi DNSSEC (ustawienie bitu CD w zapytaniach)."
 
-#: option.c:505
+#: option.c:523
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr "Upewnianie się, że odpowiedzi bez DNSSEC pochodzą ze stref niepodpisanych."
 
-#: option.c:506
+#: option.c:524
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr "Wyłączenie sprawdzania sygnatur czasowych DNSSEC do pierwszego przeładowania pamięci podręcznej."
 
-#: option.c:507
+#: option.c:525
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr "Plik znacznika czasu do weryfikacji zegara systemowego dla potrzeb DNSSEC."
 
-#: option.c:508
+#: option.c:526
 #, fuzzy
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr "Ustawianie priorytetu, okresu rozsyłania oraz czasu życia rutera (RA)."
 
-#: option.c:509
+#: option.c:527
 msgid "Do not log routine DHCP."
 msgstr "Wyłączenie logowania zwyczajnego DHCP."
 
-#: option.c:510
+#: option.c:528
 msgid "Do not log routine DHCPv6."
 msgstr "Wyłączenie logowania zwyczajnego DHCPv6."
 
-#: option.c:511
+#: option.c:529
 msgid "Do not log RA."
 msgstr "Wyłączenie logowania RA."
 
-#: option.c:512
+#: option.c:530
+msgid "Log debugging information."
+msgstr ""
+
+#: option.c:531
 msgid "Accept queries only from directly-connected networks."
 msgstr "Akceptowanie zapytań wyłącznie z sieci podpiętych bezpośrednio."
 
-#: option.c:513
+#: option.c:532
 msgid "Detect and remove DNS forwarding loops."
 msgstr "Wykrywanie i usuwanie pętli zapytań DNS."
 
-#: option.c:514
+#: option.c:533
 msgid "Ignore DNS responses containing ipaddr."
 msgstr "Ignorowanie odpowiedzi DNS zawierających ipaddr."
 
-#: option.c:515
+#: option.c:534
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr "Ustawienie TTL w odpowiedziach DNS dla adresów przydzielonych przez DHCP."
 
-#: option.c:516
+#: option.c:535
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:517
+#: option.c:536
 msgid "Enables DHCPv4 Rapid Commit option."
 msgstr ""
 
-#: option.c:518
+#: option.c:537
 msgid "Path to debug packet dump file"
 msgstr ""
 
-#: option.c:519
+#: option.c:538
 msgid "Mask which packets to dump"
 msgstr ""
 
-#: option.c:520
+#: option.c:539
 #, fuzzy
 msgid "Call dhcp-script when lease expiry changes."
 msgstr "Wywoływanie dhcp-script w reakcji na zmiany w tablicy ARP."
 
-#: option.c:725
+#: option.c:540
+msgid "Send Cisco Umbrella identifiers including remote IP."
+msgstr ""
+
+#: option.c:541
+#, fuzzy
+msgid "Do not log routine TFTP."
+msgstr "Wyłączenie logowania zwyczajnego DHCP."
+
+#: option.c:771
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -801,335 +835,378 @@ msgstr ""
 "Użycie: dnsmasq [opcje]\n"
 "\n"
 
-#: option.c:727
+#: option.c:773
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "W tym systemie w linii poleceń można używać wyłącznie jednoliterowych opcji.\n"
 
-#: option.c:729
+#: option.c:775
 #, c-format
 msgid "Valid options are:\n"
 msgstr "Dostępne opcje:\n"
 
-#: option.c:776 option.c:884
+#: option.c:822 option.c:933
 msgid "bad address"
 msgstr "zły adres"
 
-#: option.c:799 option.c:803
+#: option.c:847 option.c:851
 msgid "bad port"
 msgstr "nieprawidłowy numer portu"
 
-#: option.c:815 option.c:844 option.c:878
+#: option.c:864 option.c:893 option.c:927
 msgid "interface binding not supported"
 msgstr "nie ma możliwości dowiązywania do interfejsu"
 
-#: option.c:839 option.c:873
+#: option.c:888 option.c:922
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:852 option.c:4042
+#: option.c:901 option.c:4362
 msgid "bad interface name"
 msgstr "nieprawidłowa nazwa interfejsu"
 
-#: option.c:1184
+#: option.c:1192
+msgid "inappropriate vendor:"
+msgstr ""
+
+#: option.c:1199
+msgid "inappropriate encap:"
+msgstr ""
+
+#: option.c:1225
 msgid "unsupported encapsulation for IPv6 option"
 msgstr "nieobsługiwany rodzaj enkapsulacji opcji IPv6"
 
-#: option.c:1198
+#: option.c:1239
 msgid "bad dhcp-option"
 msgstr "błąd w dhcp-option"
 
-#: option.c:1270
+#: option.c:1317
 msgid "bad IP address"
 msgstr "zły adres IP"
 
-#: option.c:1273 option.c:1412 option.c:3297
+#: option.c:1320 option.c:1459 option.c:3551
 msgid "bad IPv6 address"
 msgstr "zły adres IPv6"
 
-#: option.c:1366
+#: option.c:1413
 msgid "bad IPv4 address"
 msgstr "nieprawidłowy adres IPv4"
 
-#: option.c:1439 option.c:1533
+#: option.c:1486 option.c:1581
 msgid "bad domain in dhcp-option"
 msgstr "nieprawidłowa nazwa domeny w dhcp-option"
 
-#: option.c:1571
+#: option.c:1625
 msgid "dhcp-option too long"
 msgstr "zbyt długa dhcp-option (>255 znaków)"
 
-#: option.c:1578
+#: option.c:1632
 msgid "illegal dhcp-match"
 msgstr "niedopuszczalne dhcp-match"
 
-#: option.c:1647
+#: option.c:1691
 msgid "illegal repeated flag"
 msgstr "wielokrotne użycie opcji niedozwolone (pojawiła się wcześniej w linii poleceń)"
 
-#: option.c:1655
+#: option.c:1699
 msgid "illegal repeated keyword"
 msgstr "wielokrotne użycie opcji niedozwolone (pojawiła się wsześniej w pliku konfiguracyjnym)"
 
-#: option.c:1726 option.c:4764
+#: option.c:1770 option.c:5080
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr "brak dostępu do katalogu %s: %s"
 
-#: option.c:1772 tftp.c:564 dump.c:68
+#: option.c:1816 tftp.c:566 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr "brak dostępu do %s: %s"
 
-#: option.c:1879
+#: option.c:1931
 msgid "setting log facility is not possible under Android"
 msgstr "zmiana log-facility w systemie Android nie jest możliwa"
 
-#: option.c:1888
+#: option.c:1940
 msgid "bad log facility"
 msgstr "nierozpoznany znacznik logów"
 
-#: option.c:1941
+#: option.c:1993
 msgid "bad MX preference"
 msgstr "nieprawidłowa wartość preferencji MX"
 
-#: option.c:1946
+#: option.c:1998
 msgid "bad MX name"
 msgstr "nieprawidłowa nazwa MX"
 
-#: option.c:1960
+#: option.c:2012
 msgid "bad MX target"
 msgstr "nieprawidłowa wartość celu MX"
 
-#: option.c:1980
+#: option.c:2032
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr "żeby mieć możliwość używania skryptów wywoływanych przy zmianie dzierżawy, przekompiluj dnsmasq-a z włączoną flagą HAVE_SCRIPT"
 
-#: option.c:1984
+#: option.c:2036
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr "używanie skryptów Lua, wymaga skompilowania dnsmasq-a z flagą HAVE_LUASCRIPT"
 
-#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
+#: option.c:2291 option.c:2327
+#, fuzzy
+msgid "bad prefix length"
+msgstr "zła maska"
+
+#: option.c:2303 option.c:2348 option.c:2398
 msgid "bad prefix"
 msgstr "zła maska"
 
-#: option.c:2658
+#: option.c:2418
+#, fuzzy
+msgid "prefix length too small"
+msgstr "długość prefiksu musi wynosić co najmniej 64"
+
+#: option.c:2697
+#, fuzzy
+msgid "Bad address in --address"
+msgstr "adres jest w użyciu"
+
+#: option.c:2751
+#, fuzzy
+msgid "bad IPv4 prefix"
+msgstr "zła maska"
+
+#: option.c:2756 option.c:3569
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "zła maska"
+
+#: option.c:2777
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr "chcąc korzystać z ipsets przekompiluj dnsmasq-a z HAVE_IPSET"
 
-#: option.c:2871
+#: option.c:2843 option.c:2861
+#, fuzzy
+msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+msgstr "chcąc korzystać z ipsets przekompiluj dnsmasq-a z HAVE_IPSET"
+
+#: option.c:3119
 msgid "bad port range"
 msgstr "nieprawidłowy zakres numerów portów"
 
-#: option.c:2897
+#: option.c:3145
 msgid "bad bridge-interface"
 msgstr "nieprawidłowa nazwa urządzenia w bridge-interface"
 
-#: option.c:2941
+#: option.c:3189
 msgid "bad shared-network"
 msgstr ""
 
-#: option.c:2996
+#: option.c:3243
 msgid "only one tag allowed"
 msgstr "można wskazać tylko jeden znacznik sieci"
 
-#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
+#: option.c:3264 option.c:3280 option.c:3406 option.c:3414 option.c:3457
 msgid "bad dhcp-range"
 msgstr "nieprawidłowy zakres dhcp-range"
 
-#: option.c:3050
+#: option.c:3298
 msgid "inconsistent DHCP range"
 msgstr "niespójny zakres adresów DHCP"
 
-#: option.c:3115
+#: option.c:3364
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr "długość prefiksu musi wynosić dokładnie 64 dla podsieci RA"
 
-#: option.c:3117
+#: option.c:3366
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr "długość prefiksu musi wynosić dokładnie 64 dla konstruktorów podsieci"
 
-#: option.c:3120
+#: option.c:3369
 msgid "prefix length must be at least 64"
 msgstr "długość prefiksu musi wynosić co najmniej 64"
 
-#: option.c:3123
+#: option.c:3372
 msgid "inconsistent DHCPv6 range"
 msgstr "niespójny zakres adresów DHCPv6"
 
-#: option.c:3142
+#: option.c:3391
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr "prefiks musi wynosić zero z argumentem \"constructor:\""
 
-#: option.c:3262 option.c:3340
+#: option.c:3516 option.c:3594
 msgid "bad hex constant"
 msgstr "zapis niezgodny z formatem szesnastkowym"
 
-#: option.c:3315
-#, fuzzy
-msgid "bad IPv6 prefix"
-msgstr "zła maska"
-
-#: option.c:3362
+#: option.c:3617
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "powtórzony adres IP %s w specyfikacji dhcp-host"
 
-#: option.c:3422
+#: option.c:3678
 msgid "bad DHCP host name"
 msgstr "niedopuszczalna nazwa komputera w dhcp-host"
 
-#: option.c:3508
+#: option.c:3764
 msgid "bad tag-if"
 msgstr "nieprawidłowa składnia 'tag-if'"
 
-#: option.c:3851 option.c:4324
+#: option.c:4107 option.c:4623
 msgid "invalid port number"
 msgstr "nieprawidłowy numer portu"
 
-#: option.c:3907
+#: option.c:4163
 msgid "bad dhcp-proxy address"
 msgstr "zły adres dhcp-proxy"
 
-#: option.c:3935
+#: option.c:4204
 msgid "Bad dhcp-relay"
 msgstr "zły dhcp-relay"
 
-#: option.c:3979
+#: option.c:4248
 msgid "bad RA-params"
 msgstr "nieprawidłowe argumenty RA"
 
-#: option.c:3989
+#: option.c:4258
 msgid "bad DUID"
 msgstr "zły DUID"
 
-#: option.c:4023
+#: option.c:4292
 #, fuzzy
 msgid "missing address in alias"
 msgstr "niepoprawny adres"
 
-#: option.c:4029
+#: option.c:4298
 msgid "invalid alias range"
 msgstr "nieprawidłowy zakres adresów w --alias"
 
-#: option.c:4081 option.c:4097
+#: option.c:4347
+#, fuzzy
+msgid "missing address in dynamic host"
+msgstr "niepoprawny adres"
+
+#: option.c:4362
+#, fuzzy
+msgid "bad dynamic host"
+msgstr "zły katalog dynamiczny %s: %s"
+
+#: option.c:4380 option.c:4396
 msgid "bad CNAME"
 msgstr "zła CNAME"
 
-#: option.c:4105
+#: option.c:4404
 msgid "duplicate CNAME"
 msgstr "powtórzona CNAME"
 
-#: option.c:4132
+#: option.c:4431
 msgid "bad PTR record"
 msgstr "nieprawidłowy zapis rekordu PTR"
 
-#: option.c:4167
+#: option.c:4466
 msgid "bad NAPTR record"
 msgstr "nieprawidłowy zapis rekordu NAPTR"
 
-#: option.c:4203
+#: option.c:4502
 msgid "bad RR record"
 msgstr "nieprawidłowy zapis rekordu RR"
 
-#: option.c:4236
+#: option.c:4535
 #, fuzzy
 msgid "bad CAA record"
 msgstr "nieprawidłowy zapis rekordu RR"
 
-#: option.c:4265
+#: option.c:4564
 msgid "bad TXT record"
 msgstr "nieprawidłowy zapis rekordu TXT"
 
-#: option.c:4308
+#: option.c:4607
 msgid "bad SRV record"
 msgstr "nieprawidłowy zapis rekordu SRV"
 
-#: option.c:4315
+#: option.c:4614
 msgid "bad SRV target"
 msgstr "nieprawidłowa wartość celu SRV"
 
-#: option.c:4334
+#: option.c:4633
 msgid "invalid priority"
 msgstr "nieprawidłowy priorytet"
 
-#: option.c:4339
+#: option.c:4638
 msgid "invalid weight"
 msgstr "nieprawidłowa waga"
 
-#: option.c:4362
+#: option.c:4661
 msgid "Bad host-record"
 msgstr "nieprawidłowy zapis host-record"
 
-#: option.c:4402
+#: option.c:4700
 msgid "Bad name in host-record"
 msgstr "niedopuszczalna nazwa w host-record"
 
-#: option.c:4444
+#: option.c:4742
 msgid "bad value for dnssec-check-unsigned"
 msgstr ""
 
-#: option.c:4480
+#: option.c:4778
 msgid "bad trust anchor"
 msgstr "nieprawidłowa specyfikacja punktu zaufania"
 
-#: option.c:4496
+#: option.c:4794
 msgid "bad HEX in trust anchor"
 msgstr "zły zapis szesnastkowy"
 
-#: option.c:4507
+#: option.c:4805
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr "nieobsługiwana opcja (sprawdź, czy obsługa DHCP/TFTP/DNSSEC/DBus została wkompilowana)"
 
-#: option.c:4567
+#: option.c:4865
 msgid "missing \""
 msgstr "brakuje \""
 
-#: option.c:4624
+#: option.c:4922
 msgid "bad option"
 msgstr "nieprawidłowa opcja"
 
-#: option.c:4626
+#: option.c:4924
 msgid "extraneous parameter"
 msgstr "nadwyżkowy parametr"
 
-#: option.c:4628
+#: option.c:4926
 msgid "missing parameter"
 msgstr "brak parametru"
 
-#: option.c:4630
+#: option.c:4928
 msgid "illegal option"
 msgstr "niedopuszczalna opcja"
 
-#: option.c:4637
+#: option.c:4935
 msgid "error"
 msgstr "błąd"
 
-#: option.c:4639
+#: option.c:4937
 #, c-format
 msgid " at line %d of %s"
 msgstr " w linii %d pliku %s"
 
-#: option.c:4654 option.c:4939 option.c:4950
+#: option.c:4952 option.c:5229 option.c:5240
 #, c-format
 msgid "read %s"
 msgstr "przeczytałem %s"
 
-#: option.c:4717 option.c:4840 tftp.c:754
+#: option.c:5015 option.c:5162 tftp.c:775
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "błąd odczytu z pliku %s: %s"
 
-#: option.c:5027
+#: option.c:5316
 msgid "junk found in command line"
 msgstr "jakieś śmieci w linii poleceń"
 
-#: option.c:5067
+#: option.c:5356
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Dnsmasq, wersja %s  %s\n"
 
-#: option.c:5068
+#: option.c:5357
 #, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1138,553 +1215,588 @@ msgstr ""
 "Wkompilowane opcje %s\n"
 "\n"
 
-#: option.c:5069
+#: option.c:5358
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Autor nie daje ŻADNYCH GWARANCJI egzekwowalnych prawnie.\n"
 
-#: option.c:5070
+#: option.c:5359
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsmasq jest wolnym oprogramowaniem, możesz go rozprowadzać\n"
 
-#: option.c:5071
+#: option.c:5360
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "na warunkach określonych w GNU General Public Licence, w wersji 2 lub 3.\n"
 
-#: option.c:5088
+#: option.c:5377
 msgid "try --help"
 msgstr "spróbuj: --help"
 
-#: option.c:5090
+#: option.c:5379
 msgid "try -w"
 msgstr "spróbuj: -w"
 
-#: option.c:5092
+#: option.c:5381
 #, c-format
 msgid "bad command line options: %s"
 msgstr "nieprawidłowa opcja w linii poleceń %s"
 
-#: option.c:5161
+#: option.c:5450
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:5195
+#: option.c:5491
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "nie można pobrać nazwy hosta: %s"
 
-#: option.c:5223
+#: option.c:5519
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "w trybie no-poll można wskazać najwyżej jeden plik resolv.conf."
 
-#: option.c:5233
+#: option.c:5529
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "musisz mieć dokładnie jeden plik resolv.conf do odczytu domen."
 
-#: option.c:5236 network.c:1594 dhcp.c:876
+#: option.c:5532 network.c:1670 dhcp.c:880
 #, c-format
 msgid "failed to read %s: %s"
 msgstr "nie udało się odczytać %s: %s"
 
-#: option.c:5253
+#: option.c:5549
 #, c-format
 msgid "no search directive found in %s"
 msgstr "brak wytycznych wyszukiwania w %s"
 
-#: option.c:5274
+#: option.c:5570
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr "w przypadku używania --dhcp-fqdn trzeba wskazać domyślną domenę"
 
-#: option.c:5283
+#: option.c:5579
 msgid "syntax check OK"
 msgstr "składnia sprawdzona, jest prawidłowa"
 
-#: forward.c:99
+#: forward.c:104
 #, c-format
 msgid "failed to send packet: %s"
 msgstr "wysyłanie pakietu nie powiodło się: %s"
 
-#: forward.c:614
+#: forward.c:601
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr "odrzucam odpowiedź DNS: nie zgadza się specyfikacja podsieci"
 
-#: forward.c:677
+#: forward.c:666
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "serwer nazw %s odmawia wykonania zapytania rekurencyjnego"
 
-#: forward.c:709
+#: forward.c:702
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr "prawdopodobnie wykryto atak DNS-rebind: %s"
 
-#: forward.c:961
+#: forward.c:1074
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1370 forward.c:1830
+#: forward.c:1381 forward.c:1910
 msgid "Ignoring query from non-local network"
 msgstr "Ignorowanie zapytań z sieci pozalokalnych."
 
-#: forward.c:2321
+#: forward.c:2198
+#, fuzzy, c-format
+msgid "failed to bind server socket to %s: %s"
+msgstr "błąd przy przyznawaniu nazwy gniazdu serwera %s: %s"
+
+#: forward.c:2494
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Osiągnięto graniczną ilość jednocześnie obsługiwanych zapytań DNS (maks: %d)"
 
-#: network.c:698
+#: forward.c:2496
+#, fuzzy, c-format
+msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+msgstr "Osiągnięto graniczną ilość jednocześnie obsługiwanych zapytań DNS (maks: %d)"
+
+#: network.c:670
+#, c-format
+msgid "stopped listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:867
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "nie udało się otworzyć gniazda %s: %s"
 
-#: network.c:1002
+#: network.c:1148
+#, c-format
+msgid "listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:1175
+#, fuzzy, c-format
+msgid "listening on %s port %d"
+msgstr "błąd wysyłania pliku %s do komputera %s"
+
+#: network.c:1208
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr "UWAGA: nasłuchiwanie na %s może przyjmować żądania przychodzące przez interfejsy inne niż %s"
 
-#: network.c:1009
+#: network.c:1215
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr "UWAGA: zastosowanie --bind-dynamic zamiast --bind-interfaces daje ochronę przed atakami wzmocnienia DNS"
 
-#: network.c:1018
+#: network.c:1224
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "uwaga: %s niedostępny"
 
-#: network.c:1027
+#: network.c:1233
 #, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "uwaga: nie znaleziono adresu interfejsu %s"
 
-#: network.c:1085
+#: network.c:1291
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "interfejs %s nie pozwolił się przyłączyć do grupy rozgłoszeniowej DHCPv6: %s"
 
-#: network.c:1090
+#: network.c:1296
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr "spróbuj podwyższyć /proc/sys/net/core/optmem_max"
 
-#: network.c:1307
+#: network.c:1492
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "błąd przy przyznawaniu nazwy gniazdu serwera %s: %s"
 
-#: network.c:1499
+#: network.c:1569
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignorowanie serwera nazw %s - interfejs lokalny"
 
-#: network.c:1510
+#: network.c:1580
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignorowanie serwera nazw %s - nie można utworzyć/dowiązać gniazda: %s"
 
-#: network.c:1530
+#: network.c:1598
 msgid "(no DNSSEC)"
 msgstr "(brak obsługi DNSSEC)"
 
-#: network.c:1533
+#: network.c:1601
 msgid "unqualified"
 msgstr "niekwalifikowane(-a)"
 
-#: network.c:1533
+#: network.c:1601
 msgid "names"
 msgstr "nazwy"
 
-#: network.c:1535
+#: network.c:1603
 msgid "default"
 msgstr "domyślne"
 
-#: network.c:1537
+#: network.c:1605
 msgid "domain"
 msgstr "domeny"
 
-#: network.c:1543
+#: network.c:1607
 #, fuzzy, c-format
-msgid "using only locally-known addresses for %s %s"
-msgstr "używam adresów lokalnych tylko dla %s %s"
-
-#: network.c:1546
-#, c-format
-msgid "using standard nameservers for %s %s"
-msgstr "używam standardowych serwerów nazw dla %s %s"
-
-#: network.c:1548
-#, c-format
-msgid "using nameserver %s#%d for %s %s %s"
+msgid "using nameserver %s#%d for %s %s%s %s"
 msgstr "używam serwera nazw %s#%d dla %s %s %s"
 
-#: network.c:1552
+#: network.c:1611
 #, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "NIE używam serwera nazw %s#%d - wykryto pętlę zapytań"
 
-#: network.c:1555
+#: network.c:1614
 #, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "używam serwera nazw %s#%d (przez %s)"
 
-#: network.c:1557
+#: network.c:1616
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "używam serwera nazw %s#%d"
 
-#: network.c:1562
+#: network.c:1630
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s"
+msgstr "używam adresów lokalnych tylko dla %s %s"
+
+#: network.c:1633
+#, fuzzy, c-format
+msgid "using standard nameservers for %s"
+msgstr "używam standardowych serwerów nazw dla %s %s"
+
+#: network.c:1637
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "używam o %d serwerów nazw więcej"
 
-#: network.c:1564
+#: network.c:1639
 #, c-format
 msgid "using %d more nameservers"
 msgstr "używam o %d serwerów nazw więcej"
 
-#: dnsmasq.c:173
+#: dnsmasq.c:184
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr "dhcp-hostsdir, dhcp-optsdir i hostsdir nie znajdują zastosowania na tej platformie"
 
-#: dnsmasq.c:188
+#: dnsmasq.c:199
 msgid "no root trust anchor provided for DNSSEC"
 msgstr "nie wskazano punktów zaufania dla DNSSEC"
 
-#: dnsmasq.c:191
+#: dnsmasq.c:202
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr "brak możliwości zmniejszenia pamięci podręcznej poniżej wielkości domyślnej w przypadku używania DNSSEC"
 
-#: dnsmasq.c:193
+#: dnsmasq.c:204
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "obsługa DNSSEC niedostępna - ustaw HAVE_DNSSEC w src/config.h"
 
-#: dnsmasq.c:199
+#: dnsmasq.c:210
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "Serwer TFTP nie został wkompilowany -- ustaw HAVE_TFTP w src/config.h"
 
-#: dnsmasq.c:204
+#: dnsmasq.c:217
 msgid "cannot use --conntrack AND --query-port"
 msgstr "--conntrack i --query-port wzajemnie się wykluczają"
 
-#: dnsmasq.c:207
+#: dnsmasq.c:223
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "wsparcie przekazywania znaczników połączeń (conntrack) nie zostało wkompilowane - ustaw HAVE_CONNTRACK w src/config.h"
 
-#: dnsmasq.c:212
+#: dnsmasq.c:228
 msgid "asynchronous logging is not available under Solaris"
 msgstr "zapis do logów w trybie asynchronicznym nie jest dostępny w Solarisie"
 
-#: dnsmasq.c:217
+#: dnsmasq.c:233
 msgid "asynchronous logging is not available under Android"
 msgstr "zapis do logów w trybie asynchronicznym nie jest dostępny w Androidzie"
 
-#: dnsmasq.c:222
+#: dnsmasq.c:238
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "tryb autorytatywny DNS-a niedostępny - ustaw HAVE_AUTH w src/config.h"
 
-#: dnsmasq.c:227
+#: dnsmasq.c:243
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "wykrywanie pętli zapytań nie zostało wkompilowane - ustaw HAVE_LOOP w src/config.h"
 
-#: dnsmasq.c:232
+#: dnsmasq.c:248
 #, fuzzy
 msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr "Obsługa DBus nie została wkompilowana -- ustaw HAVE_DBUS w src/config.h"
 
-#: dnsmasq.c:236
+#: dnsmasq.c:259
 msgid "max_port cannot be smaller than min_port"
 msgstr "max_port nie może być niższy niż min_port"
 
-#: dnsmasq.c:243
+#: dnsmasq.c:266
 msgid "--auth-server required when an auth zone is defined."
 msgstr ""
 
-#: dnsmasq.c:248
+#: dnsmasq.c:271
 msgid "zone serial must be configured in --auth-soa"
 msgstr "za pomocą --auth-soa musi zostać ustawiony numer seryjny strefy"
 
-#: dnsmasq.c:268
+#: dnsmasq.c:291
 msgid "dhcp-range constructor not available on this platform"
 msgstr "konstrukcja dhcp-range nie jest dostępna w tym systemie"
 
-#: dnsmasq.c:332
+#: dnsmasq.c:355
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr "--bind-interfaces i --bind-dynamic wzajemnie się wykluczają"
 
-#: dnsmasq.c:335
+#: dnsmasq.c:358
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "błąd podczas tworzenia listy interfejsów sieciowych: %s"
 
-#: dnsmasq.c:344
+#: dnsmasq.c:367
 #, c-format
 msgid "unknown interface %s"
 msgstr "nieznany interfejs %s"
 
-#: dnsmasq.c:406
+#: dnsmasq.c:437
 #, fuzzy
 msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
 msgstr "Obsługa DBus nie została wkompilowana -- ustaw HAVE_DBUS w src/config.h"
 
-#: dnsmasq.c:416 dnsmasq.c:1171
+#: dnsmasq.c:445 dnsmasq.c:1207
 #, c-format
 msgid "DBus error: %s"
 msgstr "błąd DBus: %s"
 
-#: dnsmasq.c:419
+#: dnsmasq.c:448
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "Obsługa DBus nie została wkompilowana -- ustaw HAVE_DBUS w src/config.h"
 
-#: dnsmasq.c:429
+#: dnsmasq.c:456 dnsmasq.c:1228
+#, fuzzy, c-format
+msgid "UBus error: %s"
+msgstr "błąd DBus: %s"
+
+#: dnsmasq.c:459
 #, fuzzy
 msgid "UBus not available: set HAVE_UBUS in src/config.h"
 msgstr "Obsługa DBus nie została wkompilowana -- ustaw HAVE_DBUS w src/config.h"
 
-#: dnsmasq.c:459
+#: dnsmasq.c:489
 #, c-format
 msgid "unknown user or group: %s"
 msgstr "nieznany użytkownik lub grupa: %s"
 
-#: dnsmasq.c:535
+#: dnsmasq.c:565
 #, c-format
 msgid "process is missing required capability %s"
 msgstr ""
 
-#: dnsmasq.c:567
+#: dnsmasq.c:597
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr "nie potrafię wejść do głównego katalogu: %s"
 
-#: dnsmasq.c:815
+#: dnsmasq.c:845
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr "uruchomiony, wersja %s, DNS wyłączony"
 
-#: dnsmasq.c:820
+#: dnsmasq.c:850
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "uruchomiony, wersja %s, %d miejsc w pamięci podręcznej"
 
-#: dnsmasq.c:822
+#: dnsmasq.c:852
 msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
 msgstr ""
 
-#: dnsmasq.c:825
+#: dnsmasq.c:855
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "uruchomiony, wersja %s, pamięć podręczna wyłączona"
 
-#: dnsmasq.c:828
+#: dnsmasq.c:858
 msgid "DNS service limited to local subnets"
 msgstr "usługa DNS ograniczona do lokalnych podsieci"
 
-#: dnsmasq.c:831
+#: dnsmasq.c:861
 #, c-format
 msgid "compile time options: %s"
 msgstr "opcje kompilacji: %s"
 
-#: dnsmasq.c:840
+#: dnsmasq.c:870
 msgid "DBus support enabled: connected to system bus"
 msgstr "obsługa DBus włączona, podłączono do serwera DBus"
 
-#: dnsmasq.c:842
+#: dnsmasq.c:872
 msgid "DBus support enabled: bus connection pending"
 msgstr "obsługa DBus włączona, trwa podłączanie do serwera DBus"
 
-#: dnsmasq.c:850
+#: dnsmasq.c:880
 #, fuzzy
 msgid "UBus support enabled: connected to system bus"
 msgstr "obsługa DBus włączona, podłączono do serwera DBus"
 
-#: dnsmasq.c:852
+#: dnsmasq.c:882
 #, fuzzy
 msgid "UBus support enabled: bus connection pending"
 msgstr "obsługa DBus włączona, trwa podłączanie do serwera DBus"
 
-#: dnsmasq.c:872
+#: dnsmasq.c:902
 msgid "DNSSEC validation enabled but all unsigned answers are trusted"
 msgstr ""
 
-#: dnsmasq.c:874
+#: dnsmasq.c:904
 msgid "DNSSEC validation enabled"
 msgstr "walidacja DNSSEC włączona"
 
-#: dnsmasq.c:878
+#: dnsmasq.c:908
 #, fuzzy
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr "sprawdzanie sygnatur czasowych DNSSEC wyłączone do czasu przeładowania pamięci podręcznej"
 
-#: dnsmasq.c:881
+#: dnsmasq.c:911
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr "sprawdzanie sygnatur czasowych DNSSEC wyłączone do czasu zsynchronizowania się zegara systemowego"
 
-#: dnsmasq.c:884
+#: dnsmasq.c:914
 #, c-format
 msgid "configured with trust anchor for %s keytag %u"
 msgstr ""
 
-#: dnsmasq.c:890
+#: dnsmasq.c:920
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "uwaga: nie udało się zmienić użytkownika pliku %s: %s"
 
-#: dnsmasq.c:894
+#: dnsmasq.c:924
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "ustawiam --bind-interfaces z powodu ograniczeń systemu operacyjnego"
 
-#: dnsmasq.c:906
+#: dnsmasq.c:936
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "uwaga: interfejs %s nie jest włączony"
 
-#: dnsmasq.c:911
+#: dnsmasq.c:941
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr "uwaga: ignoruję opcję resolv-file, ponieważ wybrano tryb no-resolv"
 
-#: dnsmasq.c:914
+#: dnsmasq.c:944
 msgid "warning: no upstream servers configured"
 msgstr "uwaga: nie wskazano nadrzędnych serwerów DNS"
 
-#: dnsmasq.c:918
+#: dnsmasq.c:948
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr "włączono asynchroniczny tryb zapisu do logów z kolejką na %d komunikatów"
 
-#: dnsmasq.c:939
+#: dnsmasq.c:969
 msgid "IPv6 router advertisement enabled"
 msgstr "anonsowanie rutera IPv6 włączone"
 
-#: dnsmasq.c:944
+#: dnsmasq.c:974
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr "DHCP, gniazda dowiązane na wyłączność interfejsowi %s"
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "root is "
 msgstr "z głównym katalogiem w "
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "enabled"
 msgstr "włączony"
 
-#: dnsmasq.c:960
+#: dnsmasq.c:993
 msgid "secure mode"
 msgstr "w trybie bezpiecznym"
 
-#: dnsmasq.c:961
+#: dnsmasq.c:994
 #, fuzzy
 msgid "single port mode"
 msgstr "nieprawidłowy numer portu"
 
-#: dnsmasq.c:964
+#: dnsmasq.c:997
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr "uwaga: %s niedostępny"
 
-#: dnsmasq.c:968
+#: dnsmasq.c:1001
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr "uwaga: katalog TFTP %s nie jest dostępny"
 
-#: dnsmasq.c:994
+#: dnsmasq.c:1027
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr "ograniczam ilość jednoczesnych przesłań TFTP do %d"
 
-#: dnsmasq.c:1173
+#: dnsmasq.c:1204
 msgid "connected to system DBus"
 msgstr "podłączono do DBus-a"
 
-#: dnsmasq.c:1345
+#: dnsmasq.c:1225
+#, fuzzy
+msgid "connected to system UBus"
+msgstr "podłączono do DBus-a"
+
+#: dnsmasq.c:1391
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr "nie potrafię przełączyć się do pracy w tle: %s"
 
-#: dnsmasq.c:1349
+#: dnsmasq.c:1395
 #, c-format
 msgid "failed to create helper: %s"
 msgstr "nie udało się utworzyć procesu pomocniczego: %s"
 
-#: dnsmasq.c:1353
+#: dnsmasq.c:1399
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr "nie powiodło się ustawianie ograniczeń (capabilities): %s"
 
-#: dnsmasq.c:1357
+#: dnsmasq.c:1403
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "nie udało się zmienić użytkownika procesu na %s: %s"
 
-#: dnsmasq.c:1361
+#: dnsmasq.c:1407
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "nie udało się zmienić grupy procesu na %s: %s"
 
-#: dnsmasq.c:1365
+#: dnsmasq.c:1411
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "nie udało się otworzyć pliku z PID-em %s: %s"
 
-#: dnsmasq.c:1369
+#: dnsmasq.c:1415
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr "nie udało się otworzyć logu %s: %s"
 
-#: dnsmasq.c:1373
+#: dnsmasq.c:1419
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr "nie udało się wczytać skryptu Lua: %s"
 
-#: dnsmasq.c:1377
+#: dnsmasq.c:1423
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr "katalog TFTP %s nie jest dostępny: %s"
 
-#: dnsmasq.c:1381
+#: dnsmasq.c:1427
 #, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "nie potrafię utworzyć pliku znacznika czasu %s: %s"
 
-#: dnsmasq.c:1465
+#: dnsmasq.c:1511
 #, c-format
 msgid "script process killed by signal %d"
 msgstr "skrypt został zabity sygnałem %d"
 
-#: dnsmasq.c:1469
+#: dnsmasq.c:1515
 #, c-format
 msgid "script process exited with status %d"
 msgstr "skrypt zakończył się z kodem powrotu %d"
 
-#: dnsmasq.c:1473
+#: dnsmasq.c:1519
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr "nie udało się uruchomić %s: %s"
 
-#: dnsmasq.c:1513
+#: dnsmasq.c:1559
 msgid "now checking DNSSEC signature timestamps"
 msgstr "trwa sprawdzanie sygnatur czasowych podpisów DNSSEC"
 
-#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
+#: dnsmasq.c:1594 dnssec.c:160 dnssec.c:204
 #, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "nie udało się uaktualnić znacznika czasu pliku %s: %s"
 
-#: dnsmasq.c:1560
+#: dnsmasq.c:1606
 msgid "exiting on receipt of SIGTERM"
 msgstr "zakończyłem działanie z powodu odebrania SIGTERM"
 
-#: dnsmasq.c:1588
+#: dnsmasq.c:1634
 #, c-format
 msgid "failed to access %s: %s"
 msgstr "brak dostępu do %s: %s"
 
-#: dnsmasq.c:1618
+#: dnsmasq.c:1664
 #, c-format
 msgid "reading %s"
 msgstr "czytanie %s"
 
-#: dnsmasq.c:1629
+#: dnsmasq.c:1675
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr "w %s nie znalazłem serwerów, spróbuję ponownie później"
@@ -1729,27 +1841,27 @@ msgstr "żądanie DHCP odebrano na interfejsie %s, który nie ma adresu"
 msgid "ARP-cache injection failed: %s"
 msgstr "uzupełnienie pamięci podręcznej ARP nie powiodło się: %s"
 
-#: dhcp.c:471
+#: dhcp.c:473
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr "Błąd wysyłania pakietu DHCP do %s: %s"
 
-#: dhcp.c:526
+#: dhcp.c:530
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "zakres adresów DHCP %s -- %s jest niespójny z maską sieci %s"
 
-#: dhcp.c:914
+#: dhcp.c:918
 #, c-format
 msgid "bad line at %s line %d"
 msgstr "zła zawartość pliku %s, w linii %d"
 
-#: dhcp.c:957
+#: dhcp.c:961
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr "w %s pomijam linię %d -- powtórzona nazwa lub adres IP"
 
-#: dhcp.c:1100 rfc3315.c:2139
+#: dhcp.c:1105 rfc3315.c:2182
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr "przekazywanie DHCP %s -> %s"
@@ -1794,8 +1906,8 @@ msgid "lease-init script returned exit code %s"
 msgstr "skrypt zakończył się z kodem powrotu %s"
 
 #: lease.c:381
-#, c-format
-msgid "failed to write %s: %s (retry in %us)"
+#, fuzzy, c-format
+msgid "failed to write %s: %s (retry in %u s)"
 msgstr "błąd zapisu do %s: %s (spróbuję ponownie za %us)"
 
 #: lease.c:955
@@ -1803,203 +1915,203 @@ msgstr "błąd zapisu do %s: %s (spróbuję ponownie za %us)"
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr "Nie uwzględniam części domenowej (%s) dla komputera %s"
 
-#: rfc2131.c:372
-#, c-format
-msgid "no address range available for DHCP request %s %s"
-msgstr "nie zdefiniowano zakresu adresów odpowiedniego dla żądania %s %s"
-
-#: rfc2131.c:373
+#: rfc2131.c:378
 msgid "with subnet selector"
 msgstr "z wyborem podsieci"
 
-#: rfc2131.c:373
+#: rfc2131.c:383
 msgid "via"
 msgstr "przez"
 
-#: rfc2131.c:385
+#: rfc2131.c:389
+#, c-format
+msgid "no address range available for DHCP request %s %s"
+msgstr "nie zdefiniowano zakresu adresów odpowiedniego dla żądania %s %s"
+
+#: rfc2131.c:403
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "%u dostępna podsieć DHCP: %s/%s"
 
-#: rfc2131.c:388 rfc3315.c:319
+#: rfc2131.c:409 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr "%u dostępny zakres adresów DHCP: %s -- %s"
 
-#: rfc2131.c:499
+#: rfc2131.c:521
 #, c-format
 msgid "%u vendor class: %s"
 msgstr "%u klasa dostawcy: %s"
 
-#: rfc2131.c:501
+#: rfc2131.c:523
 #, c-format
 msgid "%u user class: %s"
 msgstr "%u klasa użytkownika: %s"
 
-#: rfc2131.c:535
+#: rfc2131.c:557
 msgid "disabled"
 msgstr "wyłączony(a)"
 
-#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
-#: rfc3315.c:1097
+#: rfc2131.c:598 rfc2131.c:1087 rfc2131.c:1532 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1121
 msgid "ignored"
 msgstr "ignoruję"
 
-#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
+#: rfc2131.c:613 rfc2131.c:1333 rfc3315.c:867
 msgid "address in use"
 msgstr "adres jest w użyciu"
 
-#: rfc2131.c:605 rfc2131.c:1119
+#: rfc2131.c:627 rfc2131.c:1141
 msgid "no address available"
 msgstr "brak dostępnego adresu"
 
-#: rfc2131.c:612 rfc2131.c:1273
+#: rfc2131.c:634 rfc2131.c:1295
 msgid "wrong network"
 msgstr "nieprawidłowa sieć"
 
-#: rfc2131.c:627
+#: rfc2131.c:649
 msgid "no address configured"
 msgstr "brak skonfigurowanego adresu"
 
-#: rfc2131.c:633 rfc2131.c:1323
+#: rfc2131.c:655 rfc2131.c:1346
 msgid "no leases left"
 msgstr "brak wolnych dzierżaw"
 
-#: rfc2131.c:734 rfc3315.c:499
+#: rfc2131.c:756 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr "klient %u przedstawia się jako %s"
 
-#: rfc2131.c:864
+#: rfc2131.c:885
 msgid "PXE BIS not supported"
 msgstr "PXE BIS nie jest obsługiwane"
 
-#: rfc2131.c:1032 rfc3315.c:1197
+#: rfc2131.c:1054 rfc3315.c:1222
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "wyłączam statyczne przypisanie adresu %s dla %s"
 
-#: rfc2131.c:1053
+#: rfc2131.c:1075
 msgid "unknown lease"
 msgstr "nieznana dzierżawa"
 
-#: rfc2131.c:1088
+#: rfc2131.c:1110
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr "nie proponuję zakładanego w konfiguracji adresu %s, bo jest on już wydzierżawiony komputerowi %s"
 
-#: rfc2131.c:1098
+#: rfc2131.c:1120
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr "nie proponuję zakładanego w konfiguracji adresu %s, bo używa go któryś z serwerów"
 
-#: rfc2131.c:1101
+#: rfc2131.c:1123
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr "nie proponuję zakładanego w konfiguracji adresu %s, bo już poprzednio został odrzucony"
 
-#: rfc2131.c:1117 rfc2131.c:1316
+#: rfc2131.c:1139 rfc2131.c:1339
 msgid "no unique-id"
 msgstr "brak unikalnego id"
 
-#: rfc2131.c:1209
+#: rfc2131.c:1231
 msgid "wrong server-ID"
 msgstr "nieprawidłowy identyfikator serwera (server-ID)"
 
-#: rfc2131.c:1228
+#: rfc2131.c:1250
 msgid "wrong address"
 msgstr "błędny adres"
 
-#: rfc2131.c:1246 rfc3315.c:961
+#: rfc2131.c:1268 rfc3315.c:975
 msgid "lease not found"
 msgstr "dzierżawa nieznaleziona"
 
-#: rfc2131.c:1281
+#: rfc2131.c:1303
 msgid "address not available"
 msgstr "adres niedostępny"
 
-#: rfc2131.c:1292
+#: rfc2131.c:1314
 msgid "static lease available"
 msgstr "dostępna statyczna dzierżawa"
 
-#: rfc2131.c:1296
+#: rfc2131.c:1318
 msgid "address reserved"
 msgstr "adres zarezerwowany"
 
-#: rfc2131.c:1304
+#: rfc2131.c:1327
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr "porzucam przypisanie do %s nazwy %s"
 
-#: rfc2131.c:1845
+#: rfc2131.c:1866
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr "%u nazwa pliku bootowania: %s"
 
-#: rfc2131.c:1854
+#: rfc2131.c:1875
 #, c-format
 msgid "%u server name: %s"
 msgstr "%u nazwa serwera: %s"
 
-#: rfc2131.c:1862
+#: rfc2131.c:1885
 #, c-format
 msgid "%u next server: %s"
 msgstr "%u następny serwer: %s"
 
-#: rfc2131.c:1865
+#: rfc2131.c:1889
 #, c-format
 msgid "%u broadcast response"
 msgstr "%u odpowiedź rozgłoszeniowa"
 
-#: rfc2131.c:1928
+#: rfc2131.c:1952
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "nie mam możliwości wysłania opcji %d DHCP/BOOTP: niedostateczna ilość miejsca w pakiecie"
 
-#: rfc2131.c:2219
+#: rfc2131.c:2262
 msgid "PXE menu too large"
 msgstr "menu PXE zbyt duże"
 
-#: rfc2131.c:2358 rfc3315.c:1470
+#: rfc2131.c:2425 rfc3315.c:1511
 #, c-format
 msgid "%u requested options: %s"
 msgstr "%u zażądano: %s"
 
-#: rfc2131.c:2675
+#: rfc2131.c:2742
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr "nie mogę wysłać opcji RFC3925: za długi łańcuch opcji przy numerze %d"
 
-#: rfc2131.c:2738
+#: rfc2131.c:2805
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:76
+#: netlink.c:93
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "nie potrafię utworzyć połączenia netlink %s"
 
-#: netlink.c:352
+#: netlink.c:377
 #, c-format
 msgid "netlink returns error: %s"
 msgstr "wystąpił błąd w połączeniu netlink %s"
 
-#: dbus.c:438
+#: dbus.c:434
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr "opcja --%s została właśnie aktywowana za pomocą D-Bus"
 
-#: dbus.c:443
+#: dbus.c:439
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr "opcja --%s została właśnie dezaktywowana za pomocą D-Bus"
 
-#: dbus.c:717
+#: dbus.c:713
 msgid "setting upstream servers from DBus"
 msgstr "ustawiam adresy serwerów nadrzędnych na podstawie informacji odebranych z DBus"
 
-#: dbus.c:764
+#: dbus.c:760
 msgid "could not register a DBus message handler"
 msgstr "nie można zarejestrować uchwytu DBus"
 
@@ -2026,31 +2138,36 @@ msgstr "Nieznana wersja protokołu."
 msgid "lease() function missing in Lua script"
 msgstr "w skrypcie Lua brak funkcji lease()"
 
-#: tftp.c:347
+#: tftp.c:349
 msgid "unable to get free port for TFTP"
 msgstr "brak wolnego portu dla usługi TFTP"
 
-#: tftp.c:363
+#: tftp.c:365
 #, c-format
 msgid "unsupported request from %s"
 msgstr "nieobsługiwane żądanie od komputera %s"
 
-#: tftp.c:510
+#: tftp.c:512
 #, c-format
 msgid "file %s not found"
 msgstr "plik %s nie został znaleziony"
 
-#: tftp.c:628
+#: tftp.c:602
+#, c-format
+msgid "ignoring packet from %s (TID mismatch)"
+msgstr ""
+
+#: tftp.c:646
 #, c-format
 msgid "failed sending %s to %s"
 msgstr "błąd wysyłania pliku %s do komputera %s"
 
-#: tftp.c:628
+#: tftp.c:646
 #, c-format
 msgid "sent %s to %s"
 msgstr "plik %s przesłano do %s"
 
-#: tftp.c:678
+#: tftp.c:696
 #, c-format
 msgid "error %d %s received from %s"
 msgstr "błąd %d %s odebrano od %s"
@@ -2065,7 +2182,7 @@ msgstr "przepełnienie: stracono %d wpisów do logów"
 msgid "log failed: %s"
 msgstr "nie udało się zapisać komunikatów do %s"
 
-#: log.c:471
+#: log.c:477
 msgid "FAILED to start up"
 msgstr "BŁĄD: nie udało się uruchomić dnsmasq-a"
 
@@ -2118,11 +2235,11 @@ msgstr "adres MAC klienta %u: %s"
 msgid "address unavailable"
 msgstr "adres niedostępny"
 
-#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1272
 msgid "success"
 msgstr "udane"
 
-#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913 rfc3315.c:1047
 msgid "no addresses available"
 msgstr "brak wolnych adresów"
 
@@ -2130,114 +2247,114 @@ msgstr "brak wolnych adresów"
 msgid "not on link"
 msgstr "poza zasięgiem"
 
-#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
+#: rfc3315.c:979 rfc3315.c:1180 rfc3315.c:1261
 msgid "no binding found"
 msgstr "brak powiązania"
 
-#: rfc3315.c:1002
+#: rfc3315.c:1016
 msgid "deprecated"
 msgstr "przestarzały"
 
-#: rfc3315.c:1007
+#: rfc3315.c:1023
 msgid "address invalid"
 msgstr "niepoprawny adres"
 
-#: rfc3315.c:1057 rfc3315.c:1059
+#: rfc3315.c:1081 rfc3315.c:1083
 msgid "confirm failed"
 msgstr "brak potwierdzenia"
 
-#: rfc3315.c:1074
+#: rfc3315.c:1098
 msgid "all addresses still on link"
 msgstr "wszystkie adresy ciągle w użyciu"
 
-#: rfc3315.c:1165
+#: rfc3315.c:1189
 msgid "release received"
 msgstr "adres został zwolniony"
 
-#: rfc3315.c:2130
+#: rfc3315.c:2173
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr "Nie mogę rozesłać do serwerów DHCPv6 nie mając prawidłowego interfejsu"
 
-#: dhcp-common.c:145
+#: dhcp-common.c:154
 #, c-format
 msgid "Ignoring duplicate dhcp-option %d"
 msgstr "Pomijam powtórzoną dhcp-option %d"
 
-#: dhcp-common.c:222
+#: dhcp-common.c:231
 #, c-format
 msgid "%u tags: %s"
 msgstr "%u cechy: %s"
 
-#: dhcp-common.c:444
+#: dhcp-common.c:451
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr "do komputera o nazwie %s pasuje więcej niż jeden adres, w odpowiedzi DHCP wysyłam %s"
 
-#: dhcp-common.c:478
+#: dhcp-common.c:485
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "powtórzenie adresu IP %s (%s) w opcji dhcp-config"
 
-#: dhcp-common.c:542
+#: dhcp-common.c:549
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "nie udało się ustawić SO_BINDTODEVICE gniazda DHCP: %s"
 
-#: dhcp-common.c:665
+#: dhcp-common.c:672
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr "Znane opcje DHCP:\n"
 
-#: dhcp-common.c:676
+#: dhcp-common.c:683
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr "Rozpoznawane opcje DHCPv6:\n"
 
-#: dhcp-common.c:873
+#: dhcp-common.c:880
 msgid ", prefix deprecated"
 msgstr ", przestarzały prefiks"
 
-#: dhcp-common.c:876
+#: dhcp-common.c:883
 #, c-format
 msgid ", lease time "
 msgstr ", czas dzierżawy "
 
-#: dhcp-common.c:918
+#: dhcp-common.c:925
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr "%s bezstanowy na %s%.0s%.0s%s"
 
-#: dhcp-common.c:920
+#: dhcp-common.c:927
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "%s, wyłącznie statyczne dzierżawy na %.0s%s%s%.0s"
 
-#: dhcp-common.c:922
+#: dhcp-common.c:929
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr "%s, wykryto pośrednika na podsieci %.0s%s%.0s%.0s"
 
-#: dhcp-common.c:923
+#: dhcp-common.c:930
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "%s, zakres IP %s -- %s%s%.0s"
 
-#: dhcp-common.c:936
+#: dhcp-common.c:943
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr "pochodzące z DHCPv4 nazwy IPv6 na %s%s"
 
-#: dhcp-common.c:939
+#: dhcp-common.c:946
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr "anonsowanie rutera na %s%s"
 
-#: dhcp-common.c:950
+#: dhcp-common.c:957
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr "przekazywanie DHCP z %s do %s za pomocą %s"
 
-#: dhcp-common.c:952
+#: dhcp-common.c:959
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr "przekazywanie DHCP z %s do %s"
@@ -2247,32 +2364,120 @@ msgstr "przekazywanie DHCP z %s do %s"
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "nie udało się utworzyć gniazda dla ICMPv6: %s"
 
-#: auth.c:439
+#: auth.c:464
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr "ignoruję żądanie transferu strefy od %s"
 
-#: ipset.c:95
-#, c-format
-msgid "failed to find kernel version: %s"
-msgstr "niezgodna wersja jądra: %s"
-
-#: ipset.c:114
+#: ipset.c:99
 #, c-format
 msgid "failed to create IPset control socket: %s"
 msgstr "nie powiodło się otwieranie gniazda sterującego IPset: %s"
 
-#: ipset.c:226
+#: ipset.c:211
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "nie udało się uaktualnić znacznika czasu pliku %s: %s"
 
+#: pattern.c:29
+#, c-format
+msgid "[pattern.c:%d] Assertion failure: %s"
+msgstr ""
+
+#: pattern.c:142
+#, c-format
+msgid "Invalid DNS name: Invalid character %c."
+msgstr ""
+
+#: pattern.c:151
+msgid "Invalid DNS name: Empty label."
+msgstr ""
+
+#: pattern.c:156
+msgid "Invalid DNS name: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:170
+msgid "Invalid DNS name: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:176
+#, c-format
+msgid "Invalid DNS name: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:184
+#, c-format
+msgid "Invalid DNS name: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:189
+msgid "Invalid DNS name: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:199
+msgid "Invalid DNS name: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:204
+#, c-format
+msgid "DNS name has invalid length (%zu)."
+msgstr ""
+
+#: pattern.c:258
+#, c-format
+msgid "Invalid DNS name pattern: Invalid character %c."
+msgstr ""
+
+#: pattern.c:267
+msgid "Invalid DNS name pattern: Empty label."
+msgstr ""
+
+#: pattern.c:272
+msgid "Invalid DNS name pattern: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:285
+msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+msgstr ""
+
+#: pattern.c:295
+msgid "Invalid DNS name pattern: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:301
+#, c-format
+msgid "Invalid DNS name pattern: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:309
+#, c-format
+msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:314
+msgid "Invalid DNS name pattern: Wildcard within final two labels."
+msgstr ""
+
+#: pattern.c:319
+msgid "Invalid DNS name pattern: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:329
+msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:334
+#, c-format
+msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
+msgstr ""
+
 #: dnssec.c:206
 #, fuzzy
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr "trwa sprawdzanie sygnatur czasowych podpisów DNSSEC"
 
-#: dnssec.c:902
+#: dnssec.c:1014
 #, c-format
 msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
 msgstr ""
@@ -2304,7 +2509,7 @@ msgstr "błąd: nie potrafię strlcpy nazwy tablicy %s"
 
 #: tables.c:101
 #, fuzzy, c-format
-msgid "IPset: error:%s"
+msgid "IPset: error: %s"
 msgstr "błąd DBus: %s"
 
 #: tables.c:108
@@ -2366,56 +2571,54 @@ msgstr "błąd odczytu z pliku %s: %s"
 msgid "bad header in %s"
 msgstr "adres jest w użyciu"
 
-#: dump.c:201
+#: dump.c:205
 #, fuzzy
 msgid "failed to write packet dump"
 msgstr "wysyłanie pakietu nie powiodło się: %s"
 
-#: dump.c:203
+#: dump.c:207
 #, c-format
 msgid "dumping UDP packet %u mask 0x%04x"
 msgstr ""
 
-#: ubus.c:52
+#: ubus.c:79
 #, c-format
 msgid "UBus subscription callback: %s subscriber(s)"
 msgstr ""
 
-#: ubus.c:73
+#: ubus.c:99
 #, fuzzy, c-format
 msgid "Cannot reconnect to UBus: %s"
 msgstr "nie udało się otworzyć logu %s: %s"
 
-#: ubus.c:89
-msgid "Cannot initialize UBus: connection failed"
-msgstr ""
-
-#: ubus.c:102
-#, fuzzy, c-format
-msgid "Cannot add object to UBus: %s"
-msgstr "nie udało się otworzyć logu %s: %s"
-
-#: ubus.c:112
-#, fuzzy
-msgid "Connected to system UBus"
-msgstr "podłączono do DBus-a"
-
-#: ubus.c:122
+#: ubus.c:135
 msgid "Cannot set UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:142
+#: ubus.c:155
 msgid "Cannot poll UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:155
+#: ubus.c:168
 msgid "Disconnecting from UBus"
 msgstr ""
 
-#: ubus.c:199
-#, fuzzy, c-format
-msgid "Failed to send UBus event: %s"
-msgstr "wysyłanie pakietu nie powiodło się: %s"
+#: ubus.c:179 ubus.c:326
+#, c-format
+msgid "UBus command failed: %d (%s)"
+msgstr ""
+
+#: hash-questions.c:40
+msgid "Failed to create SHA-256 hash object"
+msgstr ""
+
+#, fuzzy
+#~ msgid "Cannot add object to UBus: %s"
+#~ msgstr "nie udało się otworzyć logu %s: %s"
+
+#, fuzzy
+#~ msgid "Failed to send UBus event: %s"
+#~ msgstr "wysyłanie pakietu nie powiodło się: %s"
 
 #~ msgid "Specify DHCPv6 prefix class"
 #~ msgstr "Określenie prefiksu klasy DHCPv6"
index 217fd03..a07a9ce 100644 (file)
@@ -16,1650 +16,1753 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
 
-#: cache.c:559
+#: cache.c:572
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:1081
+#: cache.c:1094
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr ""
 
-#: cache.c:1103 dhcp.c:927
+#: cache.c:1116 dhcp.c:931
 #, c-format
 msgid "bad address at %s line %d"
 msgstr ""
 
-#: cache.c:1156 dhcp.c:943
+#: cache.c:1169 dhcp.c:947
 #, c-format
 msgid "bad name at %s line %d"
 msgstr ""
 
-#: cache.c:1167 dhcp.c:1018
+#: cache.c:1180 dhcp.c:1022
 #, c-format
 msgid "read %s - %d addresses"
 msgstr ""
 
-#: cache.c:1283
+#: cache.c:1296
 msgid "cleared cache"
 msgstr ""
 
-#: cache.c:1345
+#: cache.c:1358
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1391
+#: cache.c:1404
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
-#: cache.c:1415
+#: cache.c:1428
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr ""
 
-#: cache.c:1663
+#: cache.c:1674
 #, c-format
 msgid "time %lu"
 msgstr ""
 
-#: cache.c:1664
+#: cache.c:1675
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr ""
 
-#: cache.c:1666
+#: cache.c:1677
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1669
+#: cache.c:1680
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1694
+#: cache.c:1702
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
 
-#: util.c:47
+#: util.c:51
 #, c-format
 msgid "failed to seed the random number generator: %s"
 msgstr ""
 
-#: util.c:224
+#: util.c:228
 msgid "failed to allocate memory"
 msgstr ""
 
-#: util.c:281 option.c:641
+#: util.c:285 option.c:665
 msgid "could not get memory"
 msgstr ""
 
-#: util.c:302
+#: util.c:306
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr ""
 
-#: util.c:310
+#: util.c:314
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr ""
 
-#: util.c:506
+#: util.c:520
 #, c-format
 msgid "infinite"
 msgstr ""
 
-#: option.c:358
+#: util.c:808
+#, c-format
+msgid "failed to find kernel version: %s"
+msgstr ""
+
+#: option.c:372
 msgid "Specify local address(es) to listen on."
 msgstr ""
 
-#: option.c:359
+#: option.c:373
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr ""
 
-#: option.c:360
+#: option.c:374
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr ""
 
-#: option.c:361
+#: option.c:375
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr ""
 
-#: option.c:362
+#: option.c:376
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr ""
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr ""
 
-#: option.c:364
+#: option.c:378
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr ""
 
-#: option.c:365
+#: option.c:379
 msgid "Do NOT forward queries with no domain part."
 msgstr ""
 
-#: option.c:366
+#: option.c:380
 msgid "Return self-pointing MX records for local hosts."
 msgstr ""
 
-#: option.c:367
+#: option.c:381
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr ""
 
-#: option.c:368
+#: option.c:382
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr ""
 
-#: option.c:369
+#: option.c:383
 msgid "Enable DHCP in the range given with lease duration."
 msgstr ""
 
-#: option.c:370
+#: option.c:384
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr ""
 
-#: option.c:371
+#: option.c:385
 msgid "Set address or hostname for a specified machine."
 msgstr ""
 
-#: option.c:372
+#: option.c:386
 msgid "Read DHCP host specs from file."
 msgstr ""
 
-#: option.c:373
+#: option.c:387
 msgid "Read DHCP option specs from file."
 msgstr ""
 
-#: option.c:374
+#: option.c:388
 msgid "Read DHCP host specs from a directory."
 msgstr ""
 
-#: option.c:375
+#: option.c:389
 msgid "Read DHCP options from a directory."
 msgstr ""
 
-#: option.c:376
+#: option.c:390
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
-#: option.c:377
+#: option.c:391
 #, c-format
 msgid "Do NOT load %s file."
 msgstr ""
 
-#: option.c:378
+#: option.c:392
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr ""
 
-#: option.c:379
+#: option.c:393
 msgid "Read hosts files from a directory."
 msgstr ""
 
-#: option.c:380
+#: option.c:394
 msgid "Specify interface(s) to listen on."
 msgstr ""
 
-#: option.c:381
+#: option.c:395
 msgid "Specify interface(s) NOT to listen on."
 msgstr ""
 
-#: option.c:382
+#: option.c:396
 msgid "Map DHCP user class to tag."
 msgstr ""
 
-#: option.c:383
+#: option.c:397
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:384
+#: option.c:398
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
-#: option.c:386
+#: option.c:400
+msgid "Specify vendor class to match for PXE requests."
+msgstr ""
+
+#: option.c:401
 msgid "Don't do DHCP for hosts with tag set."
 msgstr ""
 
-#: option.c:387
+#: option.c:402
 msgid "Force broadcast replies for hosts with tag set."
 msgstr ""
 
-#: option.c:388
+#: option.c:403
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr ""
 
-#: option.c:389
+#: option.c:404
 msgid "Assume we are the only DHCP server on the local network."
 msgstr ""
 
-#: option.c:390
+#: option.c:405
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:391
+#: option.c:406
 msgid "Return MX records for local hosts."
 msgstr ""
 
-#: option.c:392
+#: option.c:407
 msgid "Specify an MX record."
 msgstr ""
 
-#: option.c:393
+#: option.c:408
 msgid "Specify BOOTP options to DHCP server."
 msgstr ""
 
-#: option.c:394
+#: option.c:409
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr ""
 
-#: option.c:395
+#: option.c:410
 msgid "Do NOT cache failed search results."
 msgstr ""
 
-#: option.c:396
+#: option.c:411
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr ""
 
-#: option.c:397
+#: option.c:412
 msgid "Specify options to be sent to DHCP clients."
 msgstr ""
 
-#: option.c:398
+#: option.c:413
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
-#: option.c:399
+#: option.c:414
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr ""
 
-#: option.c:400
+#: option.c:415
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr ""
 
-#: option.c:401
+#: option.c:416
 msgid "Log DNS queries."
 msgstr ""
 
-#: option.c:402
+#: option.c:417
 msgid "Force the originating port for upstream DNS queries."
 msgstr ""
 
-#: option.c:403
+#: option.c:418
 msgid "Do NOT read resolv.conf."
 msgstr ""
 
-#: option.c:404
+#: option.c:419
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr ""
 
-#: option.c:405
+#: option.c:420
 msgid "Specify path to file with server= options"
 msgstr ""
 
-#: option.c:406
+#: option.c:421
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr ""
 
-#: option.c:407
+#: option.c:422
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr ""
 
-#: option.c:408
+#: option.c:423
 msgid "Never forward queries to specified domains."
 msgstr ""
 
-#: option.c:409
+#: option.c:424
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr ""
 
-#: option.c:410
+#: option.c:425
 msgid "Specify default target in an MX record."
 msgstr ""
 
-#: option.c:411
+#: option.c:426
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr ""
 
-#: option.c:412
+#: option.c:427
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr ""
 
-#: option.c:413
+#: option.c:428
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr ""
 
-#: option.c:414
+#: option.c:429
 msgid "Specify time-to-live ceiling for cache."
 msgstr ""
 
-#: option.c:415
+#: option.c:430
 msgid "Specify time-to-live floor for cache."
 msgstr ""
 
-#: option.c:416
+#: option.c:431
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr ""
 
-#: option.c:417
+#: option.c:432
 msgid "Map DHCP vendor class to tag."
 msgstr ""
 
-#: option.c:418
+#: option.c:433
 msgid "Display dnsmasq version and copyright information."
 msgstr ""
 
-#: option.c:419
+#: option.c:434
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr ""
 
-#: option.c:420
+#: option.c:435
 msgid "Specify a SRV record."
 msgstr ""
 
-#: option.c:421
+#: option.c:436
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
-#: option.c:422
+#: option.c:437
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr ""
 
-#: option.c:423
+#: option.c:438
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:424
+#: option.c:439
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr ""
 
-#: option.c:425
+#: option.c:440
 msgid "Specify TXT DNS record."
 msgstr ""
 
-#: option.c:426
+#: option.c:441
 msgid "Specify PTR DNS record."
 msgstr ""
 
-#: option.c:427
+#: option.c:442
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
-#: option.c:428
+#: option.c:443
 msgid "Bind only to interfaces in use."
 msgstr ""
 
-#: option.c:429
+#: option.c:444
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr ""
 
-#: option.c:430
+#: option.c:445
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr ""
 
-#: option.c:431
+#: option.c:446
 msgid "Enable the UBus interface."
 msgstr ""
 
-#: option.c:432
+#: option.c:447
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr ""
 
-#: option.c:433
+#: option.c:448
 msgid "Enable dynamic address allocation for bootp."
 msgstr ""
 
-#: option.c:434
+#: option.c:449
 msgid "Map MAC address (with wildcards) to option set."
 msgstr ""
 
-#: option.c:435
+#: option.c:450
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:436
+#: option.c:451
 msgid "Specify extra networks sharing a broadcast domain for DHCP"
 msgstr ""
 
-#: option.c:437
+#: option.c:452
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:438
+#: option.c:453
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:439
+#: option.c:454
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:440
+#: option.c:455
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:441
+#: option.c:456
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:442
+#: option.c:457
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
-#: option.c:443
+#: option.c:458
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr ""
 
-#: option.c:444
+#: option.c:459
 msgid "Do not use leasefile."
 msgstr ""
 
-#: option.c:445
+#: option.c:460
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr ""
 
-#: option.c:446
+#: option.c:461
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:447
+#: option.c:462
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:448
+#: option.c:463
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:449
+#: option.c:464
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:450
+#: option.c:465
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:451
+#: option.c:466
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:452
+#: option.c:467
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:453
+#: option.c:468
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:454
+#: option.c:469
 #, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr ""
 
-#: option.c:455
+#: option.c:470
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr ""
 
-#: option.c:456
+#: option.c:471
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:457
+#: option.c:472
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:458
+#: option.c:473
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:459
+#: option.c:474
 msgid "Use only one port for TFTP server."
 msgstr ""
 
-#: option.c:460
+#: option.c:475
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:461
+#: option.c:476
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:462
+#: option.c:477
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:463
+#: option.c:478
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:464
+#: option.c:479
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:465
+#: option.c:480
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:466
+#: option.c:481
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:467
+#: option.c:482
 msgid "Set tag if client provides given name."
 msgstr ""
 
-#: option.c:468
+#: option.c:483
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
-#: option.c:469
+#: option.c:484
 msgid "Specify NAPTR DNS record."
 msgstr ""
 
-#: option.c:470
+#: option.c:485
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:471
+#: option.c:486
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:472
+#: option.c:487
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:473
+#: option.c:488
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:474
+#: option.c:489
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:475
+#: option.c:490
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:476
+#: option.c:491
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
-#: option.c:477
+#: option.c:492
 msgid "Prompt to send to PXE clients."
 msgstr ""
 
-#: option.c:478
+#: option.c:493
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:479
+#: option.c:494
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:480
+#: option.c:495
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:481
+#: option.c:496
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
-#: option.c:482
+#: option.c:497
 msgid "Add client identification to forwarded DNS queries."
 msgstr ""
 
-#: option.c:483
+#: option.c:498
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr ""
 
-#: option.c:484
+#: option.c:499
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:485
+#: option.c:500
 msgid "Ignore client identifier option sent by DHCP clients."
 msgstr ""
 
-#: option.c:486
+#: option.c:501
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:487
+#: option.c:502
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:488
+#: option.c:503
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:489
+#: option.c:504
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:490
+#: option.c:505
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr ""
 
-#: option.c:491
+#: option.c:506
+msgid "Specify host record in interface subnet"
+msgstr ""
+
+#: option.c:507
 msgid "Specify certification authority authorization record"
 msgstr ""
 
-#: option.c:492
+#: option.c:508
 msgid "Specify arbitrary DNS resource record"
 msgstr ""
 
-#: option.c:493
+#: option.c:509
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr ""
 
-#: option.c:494
+#: option.c:510
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:495
+#: option.c:511
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:496
+#: option.c:512
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:497
+#: option.c:513
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:498
+#: option.c:514
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:499
+#: option.c:515
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:500
+#: option.c:516
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:501
+#: option.c:517
+msgid "Enable filtering of DNS queries with connection-track marks."
+msgstr ""
+
+#: option.c:518
+msgid "Set allowed DNS patterns for a connection-track mark."
+msgstr ""
+
+#: option.c:519
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:502
+#: option.c:520
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:503
+#: option.c:521
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:504
+#: option.c:522
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:505
+#: option.c:523
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:506
+#: option.c:524
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:507
+#: option.c:525
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:508
+#: option.c:526
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:509
+#: option.c:527
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:510
+#: option.c:528
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:511
+#: option.c:529
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:512
+#: option.c:530
+msgid "Log debugging information."
+msgstr ""
+
+#: option.c:531
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:513
+#: option.c:532
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:514
+#: option.c:533
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:515
+#: option.c:534
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:516
+#: option.c:535
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:517
+#: option.c:536
 msgid "Enables DHCPv4 Rapid Commit option."
 msgstr ""
 
-#: option.c:518
+#: option.c:537
 msgid "Path to debug packet dump file"
 msgstr ""
 
-#: option.c:519
+#: option.c:538
 msgid "Mask which packets to dump"
 msgstr ""
 
-#: option.c:520
+#: option.c:539
 msgid "Call dhcp-script when lease expiry changes."
 msgstr ""
 
-#: option.c:725
+#: option.c:540
+msgid "Send Cisco Umbrella identifiers including remote IP."
+msgstr ""
+
+#: option.c:541
+msgid "Do not log routine TFTP."
+msgstr ""
+
+#: option.c:771
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
 "\n"
 msgstr ""
 
-#: option.c:727
+#: option.c:773
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr ""
 
-#: option.c:729
+#: option.c:775
 #, c-format
 msgid "Valid options are:\n"
 msgstr ""
 
-#: option.c:776 option.c:884
+#: option.c:822 option.c:933
 msgid "bad address"
 msgstr ""
 
-#: option.c:799 option.c:803
+#: option.c:847 option.c:851
 msgid "bad port"
 msgstr ""
 
-#: option.c:815 option.c:844 option.c:878
+#: option.c:864 option.c:893 option.c:927
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:839 option.c:873
+#: option.c:888 option.c:922
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:852 option.c:4042
+#: option.c:901 option.c:4362
 msgid "bad interface name"
 msgstr ""
 
-#: option.c:1184
+#: option.c:1192
+msgid "inappropriate vendor:"
+msgstr ""
+
+#: option.c:1199
+msgid "inappropriate encap:"
+msgstr ""
+
+#: option.c:1225
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
-#: option.c:1198
+#: option.c:1239
 msgid "bad dhcp-option"
 msgstr ""
 
-#: option.c:1270
+#: option.c:1317
 msgid "bad IP address"
 msgstr ""
 
-#: option.c:1273 option.c:1412 option.c:3297
+#: option.c:1320 option.c:1459 option.c:3551
 msgid "bad IPv6 address"
 msgstr ""
 
-#: option.c:1366
+#: option.c:1413
 msgid "bad IPv4 address"
 msgstr ""
 
-#: option.c:1439 option.c:1533
+#: option.c:1486 option.c:1581
 msgid "bad domain in dhcp-option"
 msgstr ""
 
-#: option.c:1571
+#: option.c:1625
 msgid "dhcp-option too long"
 msgstr ""
 
-#: option.c:1578
+#: option.c:1632
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1647
+#: option.c:1691
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1655
+#: option.c:1699
 msgid "illegal repeated keyword"
 msgstr ""
 
-#: option.c:1726 option.c:4764
+#: option.c:1770 option.c:5080
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr ""
 
-#: option.c:1772 tftp.c:564 dump.c:68
+#: option.c:1816 tftp.c:566 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr ""
 
-#: option.c:1879
+#: option.c:1931
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1888
+#: option.c:1940
 msgid "bad log facility"
 msgstr ""
 
-#: option.c:1941
+#: option.c:1993
 msgid "bad MX preference"
 msgstr ""
 
-#: option.c:1946
+#: option.c:1998
 msgid "bad MX name"
 msgstr ""
 
-#: option.c:1960
+#: option.c:2012
 msgid "bad MX target"
 msgstr ""
 
-#: option.c:1980
+#: option.c:2032
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1984
+#: option.c:2036
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
-#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
+#: option.c:2291 option.c:2327
+msgid "bad prefix length"
+msgstr ""
+
+#: option.c:2303 option.c:2348 option.c:2398
 msgid "bad prefix"
 msgstr ""
 
-#: option.c:2658
+#: option.c:2418
+msgid "prefix length too small"
+msgstr ""
+
+#: option.c:2697
+msgid "Bad address in --address"
+msgstr ""
+
+#: option.c:2751
+msgid "bad IPv4 prefix"
+msgstr ""
+
+#: option.c:2756 option.c:3569
+msgid "bad IPv6 prefix"
+msgstr ""
+
+#: option.c:2777
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
-#: option.c:2871
+#: option.c:2843 option.c:2861
+msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+msgstr ""
+
+#: option.c:3119
 msgid "bad port range"
 msgstr ""
 
-#: option.c:2897
+#: option.c:3145
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2941
+#: option.c:3189
 msgid "bad shared-network"
 msgstr ""
 
-#: option.c:2996
+#: option.c:3243
 msgid "only one tag allowed"
 msgstr ""
 
-#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
+#: option.c:3264 option.c:3280 option.c:3406 option.c:3414 option.c:3457
 msgid "bad dhcp-range"
 msgstr ""
 
-#: option.c:3050
+#: option.c:3298
 msgid "inconsistent DHCP range"
 msgstr ""
 
-#: option.c:3115
+#: option.c:3364
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:3117
+#: option.c:3366
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:3120
+#: option.c:3369
 msgid "prefix length must be at least 64"
 msgstr ""
 
-#: option.c:3123
+#: option.c:3372
 msgid "inconsistent DHCPv6 range"
 msgstr ""
 
-#: option.c:3142
+#: option.c:3391
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
-#: option.c:3262 option.c:3340
+#: option.c:3516 option.c:3594
 msgid "bad hex constant"
 msgstr ""
 
-#: option.c:3315
-msgid "bad IPv6 prefix"
-msgstr ""
-
-#: option.c:3362
+#: option.c:3617
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr ""
 
-#: option.c:3422
+#: option.c:3678
 msgid "bad DHCP host name"
 msgstr ""
 
-#: option.c:3508
+#: option.c:3764
 msgid "bad tag-if"
 msgstr ""
 
-#: option.c:3851 option.c:4324
+#: option.c:4107 option.c:4623
 msgid "invalid port number"
 msgstr ""
 
-#: option.c:3907
+#: option.c:4163
 msgid "bad dhcp-proxy address"
 msgstr ""
 
-#: option.c:3935
+#: option.c:4204
 msgid "Bad dhcp-relay"
 msgstr ""
 
-#: option.c:3979
+#: option.c:4248
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3989
+#: option.c:4258
 msgid "bad DUID"
 msgstr ""
 
-#: option.c:4023
+#: option.c:4292
 msgid "missing address in alias"
 msgstr ""
 
-#: option.c:4029
+#: option.c:4298
 msgid "invalid alias range"
 msgstr ""
 
-#: option.c:4081 option.c:4097
+#: option.c:4347
+msgid "missing address in dynamic host"
+msgstr ""
+
+#: option.c:4362
+msgid "bad dynamic host"
+msgstr ""
+
+#: option.c:4380 option.c:4396
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:4105
+#: option.c:4404
 msgid "duplicate CNAME"
 msgstr ""
 
-#: option.c:4132
+#: option.c:4431
 msgid "bad PTR record"
 msgstr ""
 
-#: option.c:4167
+#: option.c:4466
 msgid "bad NAPTR record"
 msgstr ""
 
-#: option.c:4203
+#: option.c:4502
 msgid "bad RR record"
 msgstr ""
 
-#: option.c:4236
+#: option.c:4535
 msgid "bad CAA record"
 msgstr ""
 
-#: option.c:4265
+#: option.c:4564
 msgid "bad TXT record"
 msgstr ""
 
-#: option.c:4308
+#: option.c:4607
 msgid "bad SRV record"
 msgstr ""
 
-#: option.c:4315
+#: option.c:4614
 msgid "bad SRV target"
 msgstr ""
 
-#: option.c:4334
+#: option.c:4633
 msgid "invalid priority"
 msgstr ""
 
-#: option.c:4339
+#: option.c:4638
 msgid "invalid weight"
 msgstr ""
 
-#: option.c:4362
+#: option.c:4661
 msgid "Bad host-record"
 msgstr ""
 
-#: option.c:4402
+#: option.c:4700
 msgid "Bad name in host-record"
 msgstr ""
 
-#: option.c:4444
+#: option.c:4742
 msgid "bad value for dnssec-check-unsigned"
 msgstr ""
 
-#: option.c:4480
+#: option.c:4778
 msgid "bad trust anchor"
 msgstr ""
 
-#: option.c:4496
+#: option.c:4794
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4507
+#: option.c:4805
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
-#: option.c:4567
+#: option.c:4865
 msgid "missing \""
 msgstr ""
 
-#: option.c:4624
+#: option.c:4922
 msgid "bad option"
 msgstr ""
 
-#: option.c:4626
+#: option.c:4924
 msgid "extraneous parameter"
 msgstr ""
 
-#: option.c:4628
+#: option.c:4926
 msgid "missing parameter"
 msgstr ""
 
-#: option.c:4630
+#: option.c:4928
 msgid "illegal option"
 msgstr ""
 
-#: option.c:4637
+#: option.c:4935
 msgid "error"
 msgstr ""
 
-#: option.c:4639
+#: option.c:4937
 #, c-format
 msgid " at line %d of %s"
 msgstr ""
 
-#: option.c:4654 option.c:4939 option.c:4950
+#: option.c:4952 option.c:5229 option.c:5240
 #, c-format
 msgid "read %s"
 msgstr ""
 
-#: option.c:4717 option.c:4840 tftp.c:754
+#: option.c:5015 option.c:5162 tftp.c:775
 #, c-format
 msgid "cannot read %s: %s"
 msgstr ""
 
-#: option.c:5027
+#: option.c:5316
 msgid "junk found in command line"
 msgstr ""
 
-#: option.c:5067
+#: option.c:5356
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr ""
 
-#: option.c:5068
+#: option.c:5357
 #, c-format
 msgid ""
 "Compile time options: %s\n"
 "\n"
 msgstr ""
 
-#: option.c:5069
+#: option.c:5358
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr ""
 
-#: option.c:5070
+#: option.c:5359
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr ""
 
-#: option.c:5071
+#: option.c:5360
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr ""
 
-#: option.c:5088
+#: option.c:5377
 msgid "try --help"
 msgstr ""
 
-#: option.c:5090
+#: option.c:5379
 msgid "try -w"
 msgstr ""
 
-#: option.c:5092
+#: option.c:5381
 #, c-format
 msgid "bad command line options: %s"
 msgstr ""
 
-#: option.c:5161
+#: option.c:5450
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:5195
+#: option.c:5491
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr ""
 
-#: option.c:5223
+#: option.c:5519
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr ""
 
-#: option.c:5233
+#: option.c:5529
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr ""
 
-#: option.c:5236 network.c:1594 dhcp.c:876
+#: option.c:5532 network.c:1670 dhcp.c:880
 #, c-format
 msgid "failed to read %s: %s"
 msgstr ""
 
-#: option.c:5253
+#: option.c:5549
 #, c-format
 msgid "no search directive found in %s"
 msgstr ""
 
-#: option.c:5274
+#: option.c:5570
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:5283
+#: option.c:5579
 msgid "syntax check OK"
 msgstr ""
 
-#: forward.c:99
+#: forward.c:104
 #, c-format
 msgid "failed to send packet: %s"
 msgstr ""
 
-#: forward.c:614
+#: forward.c:601
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:677
+#: forward.c:666
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr ""
 
-#: forward.c:709
+#: forward.c:702
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:961
+#: forward.c:1074
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1370 forward.c:1830
+#: forward.c:1381 forward.c:1910
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2321
+#: forward.c:2198
+#, c-format
+msgid "failed to bind server socket to %s: %s"
+msgstr ""
+
+#: forward.c:2494
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr ""
 
-#: network.c:698
+#: forward.c:2496
+#, c-format
+msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+msgstr ""
+
+#: network.c:670
+#, c-format
+msgid "stopped listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:867
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr ""
 
-#: network.c:1002
+#: network.c:1148
+#, c-format
+msgid "listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:1175
+#, c-format
+msgid "listening on %s port %d"
+msgstr ""
+
+#: network.c:1208
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1009
+#: network.c:1215
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1018
+#: network.c:1224
 #, c-format
 msgid "warning: using interface %s instead"
 msgstr ""
 
-#: network.c:1027
+#: network.c:1233
 #, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr ""
 
-#: network.c:1085
+#: network.c:1291
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr ""
 
-#: network.c:1090
+#: network.c:1296
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1307
+#: network.c:1492
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr ""
 
-#: network.c:1499
+#: network.c:1569
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr ""
 
-#: network.c:1510
+#: network.c:1580
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr ""
 
-#: network.c:1530
+#: network.c:1598
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1533
+#: network.c:1601
 msgid "unqualified"
 msgstr ""
 
-#: network.c:1533
+#: network.c:1601
 msgid "names"
 msgstr ""
 
-#: network.c:1535
+#: network.c:1603
 msgid "default"
 msgstr ""
 
-#: network.c:1537
+#: network.c:1605
 msgid "domain"
 msgstr ""
 
-#: network.c:1543
+#: network.c:1607
 #, c-format
-msgid "using only locally-known addresses for %s %s"
+msgid "using nameserver %s#%d for %s %s%s %s"
 msgstr ""
 
-#: network.c:1546
+#: network.c:1611
 #, c-format
-msgid "using standard nameservers for %s %s"
+msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr ""
 
-#: network.c:1548
+#: network.c:1614
 #, c-format
-msgid "using nameserver %s#%d for %s %s %s"
+msgid "using nameserver %s#%d(via %s)"
 msgstr ""
 
-#: network.c:1552
+#: network.c:1616
 #, c-format
-msgid "NOT using nameserver %s#%d - query loop detected"
+msgid "using nameserver %s#%d"
 msgstr ""
 
-#: network.c:1555
+#: network.c:1630
 #, c-format
-msgid "using nameserver %s#%d(via %s)"
+msgid "using only locally-known addresses for %s"
 msgstr ""
 
-#: network.c:1557
+#: network.c:1633
 #, c-format
-msgid "using nameserver %s#%d"
+msgid "using standard nameservers for %s"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1637
 #, c-format
 msgid "using %d more local addresses"
 msgstr ""
 
-#: network.c:1564
+#: network.c:1639
 #, c-format
 msgid "using %d more nameservers"
 msgstr ""
 
-#: dnsmasq.c:173
+#: dnsmasq.c:184
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:188
+#: dnsmasq.c:199
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:202
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:193
+#: dnsmasq.c:204
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:199
+#: dnsmasq.c:210
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:204
+#: dnsmasq.c:217
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
-#: dnsmasq.c:207
+#: dnsmasq.c:223
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:212
+#: dnsmasq.c:228
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:217
+#: dnsmasq.c:233
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
-#: dnsmasq.c:222
+#: dnsmasq.c:238
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:227
+#: dnsmasq.c:243
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:232
+#: dnsmasq.c:248
 msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:236
+#: dnsmasq.c:259
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:243
+#: dnsmasq.c:266
 msgid "--auth-server required when an auth zone is defined."
 msgstr ""
 
-#: dnsmasq.c:248
+#: dnsmasq.c:271
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:268
+#: dnsmasq.c:291
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:332
+#: dnsmasq.c:355
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
-#: dnsmasq.c:335
+#: dnsmasq.c:358
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr ""
 
-#: dnsmasq.c:344
+#: dnsmasq.c:367
 #, c-format
 msgid "unknown interface %s"
 msgstr ""
 
-#: dnsmasq.c:406
+#: dnsmasq.c:437
 msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:416 dnsmasq.c:1171
+#: dnsmasq.c:445 dnsmasq.c:1207
 #, c-format
 msgid "DBus error: %s"
 msgstr ""
 
-#: dnsmasq.c:419
+#: dnsmasq.c:448
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:429
-msgid "UBus not available: set HAVE_UBUS in src/config.h"
+#: dnsmasq.c:456 dnsmasq.c:1228
+#, c-format
+msgid "UBus error: %s"
 msgstr ""
 
 #: dnsmasq.c:459
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr ""
+
+#: dnsmasq.c:489
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:535
+#: dnsmasq.c:565
 #, c-format
 msgid "process is missing required capability %s"
 msgstr ""
 
-#: dnsmasq.c:567
+#: dnsmasq.c:597
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
-#: dnsmasq.c:815
+#: dnsmasq.c:845
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr ""
 
-#: dnsmasq.c:820
+#: dnsmasq.c:850
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr ""
 
-#: dnsmasq.c:822
+#: dnsmasq.c:852
 msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
 msgstr ""
 
-#: dnsmasq.c:825
+#: dnsmasq.c:855
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr ""
 
-#: dnsmasq.c:828
+#: dnsmasq.c:858
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:831
+#: dnsmasq.c:861
 #, c-format
 msgid "compile time options: %s"
 msgstr ""
 
-#: dnsmasq.c:840
+#: dnsmasq.c:870
 msgid "DBus support enabled: connected to system bus"
 msgstr ""
 
-#: dnsmasq.c:842
+#: dnsmasq.c:872
 msgid "DBus support enabled: bus connection pending"
 msgstr ""
 
-#: dnsmasq.c:850
+#: dnsmasq.c:880
 msgid "UBus support enabled: connected to system bus"
 msgstr ""
 
-#: dnsmasq.c:852
+#: dnsmasq.c:882
 msgid "UBus support enabled: bus connection pending"
 msgstr ""
 
-#: dnsmasq.c:872
+#: dnsmasq.c:902
 msgid "DNSSEC validation enabled but all unsigned answers are trusted"
 msgstr ""
 
-#: dnsmasq.c:874
+#: dnsmasq.c:904
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:878
+#: dnsmasq.c:908
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:881
+#: dnsmasq.c:911
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:884
+#: dnsmasq.c:914
 #, c-format
 msgid "configured with trust anchor for %s keytag %u"
 msgstr ""
 
-#: dnsmasq.c:890
+#: dnsmasq.c:920
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr ""
 
-#: dnsmasq.c:894
+#: dnsmasq.c:924
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr ""
 
-#: dnsmasq.c:906
+#: dnsmasq.c:936
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr ""
 
-#: dnsmasq.c:911
+#: dnsmasq.c:941
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
-#: dnsmasq.c:914
+#: dnsmasq.c:944
 msgid "warning: no upstream servers configured"
 msgstr ""
 
-#: dnsmasq.c:918
+#: dnsmasq.c:948
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:939
+#: dnsmasq.c:969
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:944
+#: dnsmasq.c:974
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "root is "
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "enabled"
 msgstr ""
 
-#: dnsmasq.c:960
+#: dnsmasq.c:993
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:961
+#: dnsmasq.c:994
 msgid "single port mode"
 msgstr ""
 
-#: dnsmasq.c:964
+#: dnsmasq.c:997
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:968
+#: dnsmasq.c:1001
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:994
+#: dnsmasq.c:1027
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
-#: dnsmasq.c:1173
+#: dnsmasq.c:1204
 msgid "connected to system DBus"
 msgstr ""
 
-#: dnsmasq.c:1345
+#: dnsmasq.c:1225
+msgid "connected to system UBus"
+msgstr ""
+
+#: dnsmasq.c:1391
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
-#: dnsmasq.c:1349
+#: dnsmasq.c:1395
 #, c-format
 msgid "failed to create helper: %s"
 msgstr ""
 
-#: dnsmasq.c:1353
+#: dnsmasq.c:1399
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
-#: dnsmasq.c:1357
+#: dnsmasq.c:1403
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1361
+#: dnsmasq.c:1407
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1365
+#: dnsmasq.c:1411
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1369
+#: dnsmasq.c:1415
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1373
+#: dnsmasq.c:1419
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr ""
 
-#: dnsmasq.c:1377
+#: dnsmasq.c:1423
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
-#: dnsmasq.c:1381
+#: dnsmasq.c:1427
 #, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1465
+#: dnsmasq.c:1511
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1469
+#: dnsmasq.c:1515
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
-#: dnsmasq.c:1473
+#: dnsmasq.c:1519
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1513
+#: dnsmasq.c:1559
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
+#: dnsmasq.c:1594 dnssec.c:160 dnssec.c:204
 #, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1560
+#: dnsmasq.c:1606
 msgid "exiting on receipt of SIGTERM"
 msgstr ""
 
-#: dnsmasq.c:1588
+#: dnsmasq.c:1634
 #, c-format
 msgid "failed to access %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1618
+#: dnsmasq.c:1664
 #, c-format
 msgid "reading %s"
 msgstr ""
 
-#: dnsmasq.c:1629
+#: dnsmasq.c:1675
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr ""
@@ -1704,27 +1807,27 @@ msgstr ""
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:471
+#: dhcp.c:473
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:526
+#: dhcp.c:530
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr ""
 
-#: dhcp.c:914
+#: dhcp.c:918
 #, c-format
 msgid "bad line at %s line %d"
 msgstr ""
 
-#: dhcp.c:957
+#: dhcp.c:961
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1100 rfc3315.c:2139
+#: dhcp.c:1105 rfc3315.c:2182
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
@@ -1769,7 +1872,7 @@ msgstr ""
 
 #: lease.c:381
 #, c-format
-msgid "failed to write %s: %s (retry in %us)"
+msgid "failed to write %s: %s (retry in %u s)"
 msgstr ""
 
 #: lease.c:955
@@ -1777,203 +1880,203 @@ msgstr ""
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
-#: rfc2131.c:372
-#, c-format
-msgid "no address range available for DHCP request %s %s"
-msgstr ""
-
-#: rfc2131.c:373
+#: rfc2131.c:378
 msgid "with subnet selector"
 msgstr ""
 
-#: rfc2131.c:373
+#: rfc2131.c:383
 msgid "via"
 msgstr ""
 
-#: rfc2131.c:385
+#: rfc2131.c:389
+#, c-format
+msgid "no address range available for DHCP request %s %s"
+msgstr ""
+
+#: rfc2131.c:403
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr ""
 
-#: rfc2131.c:388 rfc3315.c:319
+#: rfc2131.c:409 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
-#: rfc2131.c:499
+#: rfc2131.c:521
 #, c-format
 msgid "%u vendor class: %s"
 msgstr ""
 
-#: rfc2131.c:501
+#: rfc2131.c:523
 #, c-format
 msgid "%u user class: %s"
 msgstr ""
 
-#: rfc2131.c:535
+#: rfc2131.c:557
 msgid "disabled"
 msgstr ""
 
-#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
-#: rfc3315.c:1097
+#: rfc2131.c:598 rfc2131.c:1087 rfc2131.c:1532 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1121
 msgid "ignored"
 msgstr ""
 
-#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
+#: rfc2131.c:613 rfc2131.c:1333 rfc3315.c:867
 msgid "address in use"
 msgstr ""
 
-#: rfc2131.c:605 rfc2131.c:1119
+#: rfc2131.c:627 rfc2131.c:1141
 msgid "no address available"
 msgstr ""
 
-#: rfc2131.c:612 rfc2131.c:1273
+#: rfc2131.c:634 rfc2131.c:1295
 msgid "wrong network"
 msgstr ""
 
-#: rfc2131.c:627
+#: rfc2131.c:649
 msgid "no address configured"
 msgstr ""
 
-#: rfc2131.c:633 rfc2131.c:1323
+#: rfc2131.c:655 rfc2131.c:1346
 msgid "no leases left"
 msgstr ""
 
-#: rfc2131.c:734 rfc3315.c:499
+#: rfc2131.c:756 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:864
+#: rfc2131.c:885
 msgid "PXE BIS not supported"
 msgstr ""
 
-#: rfc2131.c:1032 rfc3315.c:1197
+#: rfc2131.c:1054 rfc3315.c:1222
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr ""
 
-#: rfc2131.c:1053
+#: rfc2131.c:1075
 msgid "unknown lease"
 msgstr ""
 
-#: rfc2131.c:1088
+#: rfc2131.c:1110
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1098
+#: rfc2131.c:1120
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1101
+#: rfc2131.c:1123
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1117 rfc2131.c:1316
+#: rfc2131.c:1139 rfc2131.c:1339
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1209
+#: rfc2131.c:1231
 msgid "wrong server-ID"
 msgstr ""
 
-#: rfc2131.c:1228
+#: rfc2131.c:1250
 msgid "wrong address"
 msgstr ""
 
-#: rfc2131.c:1246 rfc3315.c:961
+#: rfc2131.c:1268 rfc3315.c:975
 msgid "lease not found"
 msgstr ""
 
-#: rfc2131.c:1281
+#: rfc2131.c:1303
 msgid "address not available"
 msgstr ""
 
-#: rfc2131.c:1292
+#: rfc2131.c:1314
 msgid "static lease available"
 msgstr ""
 
-#: rfc2131.c:1296
+#: rfc2131.c:1318
 msgid "address reserved"
 msgstr ""
 
-#: rfc2131.c:1304
+#: rfc2131.c:1327
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1845
+#: rfc2131.c:1866
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
-#: rfc2131.c:1854
+#: rfc2131.c:1875
 #, c-format
 msgid "%u server name: %s"
 msgstr ""
 
-#: rfc2131.c:1862
+#: rfc2131.c:1885
 #, c-format
 msgid "%u next server: %s"
 msgstr ""
 
-#: rfc2131.c:1865
+#: rfc2131.c:1889
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1928
+#: rfc2131.c:1952
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr ""
 
-#: rfc2131.c:2219
+#: rfc2131.c:2262
 msgid "PXE menu too large"
 msgstr ""
 
-#: rfc2131.c:2358 rfc3315.c:1470
+#: rfc2131.c:2425 rfc3315.c:1511
 #, c-format
 msgid "%u requested options: %s"
 msgstr ""
 
-#: rfc2131.c:2675
+#: rfc2131.c:2742
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2738
+#: rfc2131.c:2805
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:76
+#: netlink.c:93
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr ""
 
-#: netlink.c:352
+#: netlink.c:377
 #, c-format
 msgid "netlink returns error: %s"
 msgstr ""
 
-#: dbus.c:438
+#: dbus.c:434
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:443
+#: dbus.c:439
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:717
+#: dbus.c:713
 msgid "setting upstream servers from DBus"
 msgstr ""
 
-#: dbus.c:764
+#: dbus.c:760
 msgid "could not register a DBus message handler"
 msgstr ""
 
@@ -2000,31 +2103,36 @@ msgstr ""
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:347
+#: tftp.c:349
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:363
+#: tftp.c:365
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
-#: tftp.c:510
+#: tftp.c:512
 #, c-format
 msgid "file %s not found"
 msgstr ""
 
-#: tftp.c:628
+#: tftp.c:602
+#, c-format
+msgid "ignoring packet from %s (TID mismatch)"
+msgstr ""
+
+#: tftp.c:646
 #, c-format
 msgid "failed sending %s to %s"
 msgstr ""
 
-#: tftp.c:628
+#: tftp.c:646
 #, c-format
 msgid "sent %s to %s"
 msgstr ""
 
-#: tftp.c:678
+#: tftp.c:696
 #, c-format
 msgid "error %d %s received from %s"
 msgstr ""
@@ -2039,7 +2147,7 @@ msgstr ""
 msgid "log failed: %s"
 msgstr ""
 
-#: log.c:471
+#: log.c:477
 msgid "FAILED to start up"
 msgstr ""
 
@@ -2092,11 +2200,11 @@ msgstr ""
 msgid "address unavailable"
 msgstr ""
 
-#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1272
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913 rfc3315.c:1047
 msgid "no addresses available"
 msgstr ""
 
@@ -2104,114 +2212,114 @@ msgstr ""
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
+#: rfc3315.c:979 rfc3315.c:1180 rfc3315.c:1261
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1002
+#: rfc3315.c:1016
 msgid "deprecated"
 msgstr ""
 
-#: rfc3315.c:1007
+#: rfc3315.c:1023
 msgid "address invalid"
 msgstr ""
 
-#: rfc3315.c:1057 rfc3315.c:1059
+#: rfc3315.c:1081 rfc3315.c:1083
 msgid "confirm failed"
 msgstr ""
 
-#: rfc3315.c:1074
+#: rfc3315.c:1098
 msgid "all addresses still on link"
 msgstr ""
 
-#: rfc3315.c:1165
+#: rfc3315.c:1189
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2130
+#: rfc3315.c:2173
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
-#: dhcp-common.c:145
+#: dhcp-common.c:154
 #, c-format
 msgid "Ignoring duplicate dhcp-option %d"
 msgstr ""
 
-#: dhcp-common.c:222
+#: dhcp-common.c:231
 #, c-format
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:444
+#: dhcp-common.c:451
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
-#: dhcp-common.c:478
+#: dhcp-common.c:485
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr ""
 
-#: dhcp-common.c:542
+#: dhcp-common.c:549
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr ""
 
-#: dhcp-common.c:665
+#: dhcp-common.c:672
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:676
+#: dhcp-common.c:683
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:873
+#: dhcp-common.c:880
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:876
+#: dhcp-common.c:883
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:918
+#: dhcp-common.c:925
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
-#: dhcp-common.c:920
+#: dhcp-common.c:927
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:922
+#: dhcp-common.c:929
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
-#: dhcp-common.c:923
+#: dhcp-common.c:930
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:936
+#: dhcp-common.c:943
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:939
+#: dhcp-common.c:946
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr ""
 
-#: dhcp-common.c:950
+#: dhcp-common.c:957
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:952
+#: dhcp-common.c:959
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2221,31 +2329,119 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr ""
 
-#: auth.c:439
+#: auth.c:464
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
 
-#: ipset.c:95
+#: ipset.c:99
 #, c-format
-msgid "failed to find kernel version: %s"
+msgid "failed to create IPset control socket: %s"
 msgstr ""
 
-#: ipset.c:114
+#: ipset.c:211
 #, c-format
-msgid "failed to create IPset control socket: %s"
+msgid "failed to update ipset %s: %s"
 msgstr ""
 
-#: ipset.c:226
+#: pattern.c:29
 #, c-format
-msgid "failed to update ipset %s: %s"
+msgid "[pattern.c:%d] Assertion failure: %s"
+msgstr ""
+
+#: pattern.c:142
+#, c-format
+msgid "Invalid DNS name: Invalid character %c."
+msgstr ""
+
+#: pattern.c:151
+msgid "Invalid DNS name: Empty label."
+msgstr ""
+
+#: pattern.c:156
+msgid "Invalid DNS name: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:170
+msgid "Invalid DNS name: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:176
+#, c-format
+msgid "Invalid DNS name: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:184
+#, c-format
+msgid "Invalid DNS name: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:189
+msgid "Invalid DNS name: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:199
+msgid "Invalid DNS name: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:204
+#, c-format
+msgid "DNS name has invalid length (%zu)."
+msgstr ""
+
+#: pattern.c:258
+#, c-format
+msgid "Invalid DNS name pattern: Invalid character %c."
+msgstr ""
+
+#: pattern.c:267
+msgid "Invalid DNS name pattern: Empty label."
+msgstr ""
+
+#: pattern.c:272
+msgid "Invalid DNS name pattern: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:285
+msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+msgstr ""
+
+#: pattern.c:295
+msgid "Invalid DNS name pattern: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:301
+#, c-format
+msgid "Invalid DNS name pattern: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:309
+#, c-format
+msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:314
+msgid "Invalid DNS name pattern: Wildcard within final two labels."
+msgstr ""
+
+#: pattern.c:319
+msgid "Invalid DNS name pattern: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:329
+msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:334
+#, c-format
+msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
 msgstr ""
 
 #: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: dnssec.c:902
+#: dnssec.c:1014
 #, c-format
 msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
 msgstr ""
@@ -2277,7 +2473,7 @@ msgstr ""
 
 #: tables.c:101
 #, c-format
-msgid "IPset: error:%s"
+msgid "IPset: error: %s"
 msgstr ""
 
 #: tables.c:108
@@ -2339,51 +2535,42 @@ msgstr ""
 msgid "bad header in %s"
 msgstr ""
 
-#: dump.c:201
+#: dump.c:205
 msgid "failed to write packet dump"
 msgstr ""
 
-#: dump.c:203
+#: dump.c:207
 #, c-format
 msgid "dumping UDP packet %u mask 0x%04x"
 msgstr ""
 
-#: ubus.c:52
+#: ubus.c:79
 #, c-format
 msgid "UBus subscription callback: %s subscriber(s)"
 msgstr ""
 
-#: ubus.c:73
+#: ubus.c:99
 #, c-format
 msgid "Cannot reconnect to UBus: %s"
 msgstr ""
 
-#: ubus.c:89
-msgid "Cannot initialize UBus: connection failed"
-msgstr ""
-
-#: ubus.c:102
-#, c-format
-msgid "Cannot add object to UBus: %s"
-msgstr ""
-
-#: ubus.c:112
-msgid "Connected to system UBus"
-msgstr ""
-
-#: ubus.c:122
+#: ubus.c:135
 msgid "Cannot set UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:142
+#: ubus.c:155
 msgid "Cannot poll UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:155
+#: ubus.c:168
 msgid "Disconnecting from UBus"
 msgstr ""
 
-#: ubus.c:199
+#: ubus.c:179 ubus.c:326
 #, c-format
-msgid "Failed to send UBus event: %s"
+msgid "UBus command failed: %d (%s)"
+msgstr ""
+
+#: hash-questions.c:40
+msgid "Failed to create SHA-256 hash object"
 msgstr ""
index 9d08ebb..295e629 100644 (file)
--- a/po/ro.po
+++ b/po/ro.po
@@ -15,803 +15,836 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: cache.c:559
+#: cache.c:572
 msgid "Internal error in cache."
 msgstr ""
 
 # for compatibility purposes the letters â, ă, ş, ţ and î can be written as their look-alike correspondent.
-#: cache.c:1081
+#: cache.c:1094
 #, fuzzy, c-format
 msgid "failed to load names from %s: %s"
 msgstr "încărcarea numelor din %s: %s a eşuat"
 
-#: cache.c:1103 dhcp.c:927
+#: cache.c:1116 dhcp.c:931
 #, c-format
 msgid "bad address at %s line %d"
 msgstr "adresă greşită în %s, linia %d"
 
-#: cache.c:1156 dhcp.c:943
+#: cache.c:1169 dhcp.c:947
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "nume greşit în %s linia %d"
 
-#: cache.c:1167 dhcp.c:1018
+#: cache.c:1180 dhcp.c:1022
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "citesc %s - %d adrese"
 
-#: cache.c:1283
+#: cache.c:1296
 msgid "cleared cache"
 msgstr "memoria temporară a fost ştearsă"
 
-#: cache.c:1345
+#: cache.c:1358
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1391
+#: cache.c:1404
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
-#: cache.c:1415
+#: cache.c:1428
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "nu pot da numele %s împrumutului de adresă DHCP a lui %s deoarece numeleexistă în %s cu adresa %s"
 
-#: cache.c:1663
+#: cache.c:1674
 #, c-format
 msgid "time %lu"
 msgstr ""
 
-#: cache.c:1664
+#: cache.c:1675
 #, fuzzy, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "cantitate de memorie temporară %d, %d/%d stocări temporare aureutilizat locaţii neexpirate."
 
-#: cache.c:1666
+#: cache.c:1677
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1669
+#: cache.c:1680
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1694
+#: cache.c:1702
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
 
-#: util.c:47
+#: util.c:51
 #, fuzzy, c-format
 msgid "failed to seed the random number generator: %s"
 msgstr "ascultarea pe socket a eşuat: %s"
 
-#: util.c:224
+#: util.c:228
 #, fuzzy
 msgid "failed to allocate memory"
 msgstr "nu pot încărca %d bytes"
 
-#: util.c:281 option.c:641
+#: util.c:285 option.c:665
 msgid "could not get memory"
 msgstr "nu am putut aloca memorie"
 
-#: util.c:302
+#: util.c:306
 #, fuzzy, c-format
 msgid "cannot create pipe: %s"
 msgstr "nu pot citi %s: %s"
 
-#: util.c:310
+#: util.c:314
 #, fuzzy, c-format
 msgid "failed to allocate %d bytes"
 msgstr "nu pot încărca %d bytes"
 
-#: util.c:506
+#: util.c:520
 #, c-format
 msgid "infinite"
 msgstr "infinit"
 
-#: option.c:358
+#: util.c:808
+#, fuzzy, c-format
+msgid "failed to find kernel version: %s"
+msgstr "activarea socket-ului server-ului DHCP a eşuat: %s"
+
+#: option.c:372
 msgid "Specify local address(es) to listen on."
 msgstr "Specificaţi adresele locale deservite."
 
-#: option.c:359
+#: option.c:373
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Afişează adresele IP ale maşinilor în domeniul dat."
 
-#: option.c:360
+#: option.c:374
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Simulează căutări după adresă pentru domenii de adresă private (RFC1918)."
 
-#: option.c:361
+#: option.c:375
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Interpretează adresa IP ca NXDOMAIN (împotriva manipulărilor Verisign)"
 
-#: option.c:362
+#: option.c:376
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Specifică mărimea înregistrărilor temporare (implicit e %s)."
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Specifică fişier de configurare (implicit e %s)."
 
-#: option.c:364
+#: option.c:378
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "NU porneşte în fundal: rulează în modul depanare."
 
-#: option.c:365
+#: option.c:379
 msgid "Do NOT forward queries with no domain part."
 msgstr "NU înainta cererile ce nu conţin domeniu DNS."
 
-#: option.c:366
+#: option.c:380
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Răspunde cu înregistrări MX spre el însuşi pentru maşini locale."
 
-#: option.c:367
+#: option.c:381
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Adaugă numelor simple din /etc/hosts numele domeniului ca sufix."
 
-#: option.c:368
+#: option.c:382
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "Nu inainta cereri DNS defecte provenite de la maşini Windows."
 
-#: option.c:369
+#: option.c:383
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Activează DHCP în domeniul dat cu durată limitată de împrumut."
 
-#: option.c:370
+#: option.c:384
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Rulează sub acest grup după pornire (implicit e %s)."
 
-#: option.c:371
+#: option.c:385
 msgid "Set address or hostname for a specified machine."
 msgstr "Schimbă adresa sau numele maşinii specificate."
 
-#: option.c:372
+#: option.c:386
 #, fuzzy
 msgid "Read DHCP host specs from file."
 msgstr "nume MX invalid"
 
-#: option.c:373
+#: option.c:387
 msgid "Read DHCP option specs from file."
 msgstr ""
 
-#: option.c:374
+#: option.c:388
 #, fuzzy
 msgid "Read DHCP host specs from a directory."
 msgstr "nume MX invalid"
 
-#: option.c:375
+#: option.c:389
 #, fuzzy
 msgid "Read DHCP options from a directory."
 msgstr "nume MX invalid"
 
-#: option.c:376
+#: option.c:390
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
-#: option.c:377
+#: option.c:391
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "Nu încarcă fişierul %s."
 
-#: option.c:378
+#: option.c:392
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Specifică spre citire un fişier hosts adiţional la %s."
 
-#: option.c:379
+#: option.c:393
 #, fuzzy
 msgid "Read hosts files from a directory."
 msgstr "nume MX invalid"
 
-#: option.c:380
+#: option.c:394
 msgid "Specify interface(s) to listen on."
 msgstr "Specifică interfeţele deservite."
 
-#: option.c:381
+#: option.c:395
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Specifică interfeţele NE-deservite."
 
-#: option.c:382
+#: option.c:396
 #, fuzzy
 msgid "Map DHCP user class to tag."
 msgstr "Leagă clasa de utilizator DHCP cu grup de opţiuni."
 
-#: option.c:383
+#: option.c:397
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:384
+#: option.c:398
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
-#: option.c:386
+#: option.c:400
+msgid "Specify vendor class to match for PXE requests."
+msgstr ""
+
+#: option.c:401
 #, fuzzy
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Nu furniza DHCP maşinilor din grupul de opţiuni."
 
-#: option.c:387
+#: option.c:402
 #, fuzzy
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Nu furniza DHCP maşinilor din grupul de opţiuni."
 
-#: option.c:388
+#: option.c:403
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "NU porneşte în fundal, NU rulează în modul depanare."
 
-#: option.c:389
+#: option.c:404
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Presupune că suntem singurul server DHCP din reţeaua locală."
 
-#: option.c:390
+#: option.c:405
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Specifică fişierul de stocare a împrumuturilor DHCP (implicit e %s)."
 
-#: option.c:391
+#: option.c:406
 msgid "Return MX records for local hosts."
 msgstr "Răspunde cu întregistrări MX pentru maşini locale."
 
-#: option.c:392
+#: option.c:407
 msgid "Specify an MX record."
 msgstr "Specifică o înregistrare MX."
 
-#: option.c:393
+#: option.c:408
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Specifică opţiuni BOOTP serverului DHCP."
 
-#: option.c:394
+#: option.c:409
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "Nu încărca fişierul %s, citeşte-l doar la SIGHUP."
 
-#: option.c:395
+#: option.c:410
 msgid "Do NOT cache failed search results."
 msgstr "NU memora rezultatele de căutare DNS eşuatată."
 
-#: option.c:396
+#: option.c:411
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Foloseşte servere DNS strict în ordinea dată în %s."
 
-#: option.c:397
+#: option.c:412
 #, fuzzy
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Configurează opţiuni în plusce trebuie trimise clienţilor DHCP."
 
-#: option.c:398
+#: option.c:413
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
-#: option.c:399
+#: option.c:414
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Specifică numărul portului pentru cereri DNS (implicit e 53)."
 
-#: option.c:400
+#: option.c:415
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Marimea maximă a pachetului UDP pentru EDNS.0 (implicit e %s)."
 
-#: option.c:401
+#: option.c:416
 #, fuzzy
 msgid "Log DNS queries."
 msgstr "Înregistrează tranzacţiile."
 
-#: option.c:402
+#: option.c:417
 #, fuzzy
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Forţează acest port pentru datele ce pleacă."
 
-#: option.c:403
+#: option.c:418
 msgid "Do NOT read resolv.conf."
 msgstr "NU citi fişierul resolv.conf"
 
-#: option.c:404
+#: option.c:419
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Specifică calea către resolv.conf (implicit e %s)."
 
-#: option.c:405
+#: option.c:420
 #, fuzzy
 msgid "Specify path to file with server= options"
 msgstr "Specifică o cale pentru fişierul PID. (implicit %s)."
 
-#: option.c:406
+#: option.c:421
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Specifică adresele server(elor) superioare cu domenii opţionale."
 
-#: option.c:407
+#: option.c:422
 #, fuzzy
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Specifică adresele server(elor) superioare cu domenii opţionale."
 
-#: option.c:408
+#: option.c:423
 msgid "Never forward queries to specified domains."
 msgstr "Nu înaintează cererile spre domeniile specificate."
 
-#: option.c:409
+#: option.c:424
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Specifică domeniul de transmis prin DHCP."
 
-#: option.c:410
+#: option.c:425
 msgid "Specify default target in an MX record."
 msgstr "Specifică o ţintă într-o înregistrare MX."
 
-#: option.c:411
+#: option.c:426
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Specifică TTL în secunde pentru răspunsurile din /etc/hosts."
 
-#: option.c:412
+#: option.c:427
 #, fuzzy
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Specifică TTL în secunde pentru răspunsurile din /etc/hosts."
 
-#: option.c:413
+#: option.c:428
 #, fuzzy
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Specifică TTL în secunde pentru răspunsurile din /etc/hosts."
 
-#: option.c:414
+#: option.c:429
 #, fuzzy
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Specifică TTL în secunde pentru răspunsurile din /etc/hosts."
 
-#: option.c:415
+#: option.c:430
 #, fuzzy
 msgid "Specify time-to-live floor for cache."
 msgstr "Specifică TTL în secunde pentru răspunsurile din /etc/hosts."
 
-#: option.c:416
+#: option.c:431
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Rulează sub acest utilizator după pornire. (implicit e %s)."
 
-#: option.c:417
+#: option.c:432
 #, fuzzy
 msgid "Map DHCP vendor class to tag."
 msgstr "Trimite opţiuni DHCP în funcţie de marca plăcii de reţea."
 
-#: option.c:418
+#: option.c:433
 msgid "Display dnsmasq version and copyright information."
 msgstr "Afişează versiunea dnsmasq şi drepturile de autor."
 
-#: option.c:419
+#: option.c:434
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Traduce adresele IPv4 de la serverele DNS superioare."
 
-#: option.c:420
+#: option.c:435
 msgid "Specify a SRV record."
 msgstr "Specifică o înregistrare SRV."
 
-#: option.c:421
+#: option.c:436
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
-#: option.c:422
+#: option.c:437
 #, fuzzy, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Specifică o cale pentru fişierul PID. (implicit %s)."
 
-#: option.c:423
+#: option.c:438
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
 
-#: option.c:424
+#: option.c:439
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Răspunde cererilor DNS în funcţie de interfaţa pe care a venit cererea."
 
-#: option.c:425
+#: option.c:440
 msgid "Specify TXT DNS record."
 msgstr "Specifică o înregistrare TXT."
 
-#: option.c:426
+#: option.c:441
 #, fuzzy
 msgid "Specify PTR DNS record."
 msgstr "Specifică o înregistrare TXT."
 
-#: option.c:427
+#: option.c:442
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
-#: option.c:428
+#: option.c:443
 msgid "Bind only to interfaces in use."
 msgstr "Ascultă doar pe interfeţele active."
 
-#: option.c:429
+#: option.c:444
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Citeşte informaţii DHCP statice despre maşină din %s."
 
-#: option.c:430
+#: option.c:445
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Activeaza interfaţa DBus pentru configurarea serverelor superioare."
 
-#: option.c:431
+#: option.c:446
 msgid "Enable the UBus interface."
 msgstr ""
 
-#: option.c:432
+#: option.c:447
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "Nu activează DHCP ci doar DNS pe această interfaţă."
 
-#: option.c:433
+#: option.c:448
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Activează alocarea dinamică a adreselor pentru BOOTP."
 
-#: option.c:434
+#: option.c:449
 #, fuzzy
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Trimite opţiuni DHCP în funcţie de marca plăcii de reţea."
 
-#: option.c:435
+#: option.c:450
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:436
+#: option.c:451
 msgid "Specify extra networks sharing a broadcast domain for DHCP"
 msgstr ""
 
-#: option.c:437
+#: option.c:452
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:438
+#: option.c:453
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:439
+#: option.c:454
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:440
+#: option.c:455
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:441
+#: option.c:456
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:442
+#: option.c:457
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
-#: option.c:443
+#: option.c:458
 #, fuzzy
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Rulează sub acest utilizator după pornire. (implicit e %s)."
 
-#: option.c:444
+#: option.c:459
 msgid "Do not use leasefile."
 msgstr ""
 
-#: option.c:445
+#: option.c:460
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
 
-#: option.c:446
+#: option.c:461
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:447
+#: option.c:462
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:448
+#: option.c:463
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:449
+#: option.c:464
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:450
+#: option.c:465
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:451
+#: option.c:466
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:452
+#: option.c:467
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:453
+#: option.c:468
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:454
+#: option.c:469
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
 
-#: option.c:455
+#: option.c:470
 #, fuzzy
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
 
-#: option.c:456
+#: option.c:471
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:457
+#: option.c:472
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:458
+#: option.c:473
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:459
+#: option.c:474
 msgid "Use only one port for TFTP server."
 msgstr ""
 
-#: option.c:460
+#: option.c:475
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:461
+#: option.c:476
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:462
+#: option.c:477
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:463
+#: option.c:478
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:464
+#: option.c:479
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:465
+#: option.c:480
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:466
+#: option.c:481
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:467
+#: option.c:482
 msgid "Set tag if client provides given name."
 msgstr ""
 
-#: option.c:468
+#: option.c:483
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
-#: option.c:469
+#: option.c:484
 #, fuzzy
 msgid "Specify NAPTR DNS record."
 msgstr "Specifică o înregistrare TXT."
 
-#: option.c:470
+#: option.c:485
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:471
+#: option.c:486
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:472
+#: option.c:487
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:473
+#: option.c:488
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:474
+#: option.c:489
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:475
+#: option.c:490
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:476
+#: option.c:491
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
-#: option.c:477
+#: option.c:492
 #, fuzzy
 msgid "Prompt to send to PXE clients."
 msgstr "Configurează opţiuni în plusce trebuie trimise clienţilor DHCP."
 
-#: option.c:478
+#: option.c:493
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:479
+#: option.c:494
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:480
+#: option.c:495
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:481
+#: option.c:496
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
-#: option.c:482
+#: option.c:497
 #, fuzzy
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Forţează acest port pentru datele ce pleacă."
 
-#: option.c:483
+#: option.c:498
 #, fuzzy
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Traduce adresele IPv4 de la serverele DNS superioare."
 
-#: option.c:484
+#: option.c:499
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:485
+#: option.c:500
 #, fuzzy
 msgid "Ignore client identifier option sent by DHCP clients."
 msgstr "Configurează opţiuni în plusce trebuie trimise clienţilor DHCP."
 
-#: option.c:486
+#: option.c:501
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:487
+#: option.c:502
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:488
+#: option.c:503
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:489
+#: option.c:504
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:490
+#: option.c:505
 #, fuzzy
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Specifică o înregistrare MX."
 
-#: option.c:491
+#: option.c:506
+msgid "Specify host record in interface subnet"
+msgstr ""
+
+#: option.c:507
 msgid "Specify certification authority authorization record"
 msgstr ""
 
-#: option.c:492
+#: option.c:508
 #, fuzzy
 msgid "Specify arbitrary DNS resource record"
 msgstr "Specifică o înregistrare TXT."
 
-#: option.c:493
+#: option.c:509
 #, fuzzy
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "interfaţă necunoscută %s"
 
-#: option.c:494
+#: option.c:510
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:495
+#: option.c:511
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:496
+#: option.c:512
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:497
+#: option.c:513
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:498
+#: option.c:514
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:499
+#: option.c:515
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:500
+#: option.c:516
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:501
+#: option.c:517
+msgid "Enable filtering of DNS queries with connection-track marks."
+msgstr ""
+
+#: option.c:518
+msgid "Set allowed DNS patterns for a connection-track mark."
+msgstr ""
+
+#: option.c:519
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:502
+#: option.c:520
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:503
+#: option.c:521
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:504
+#: option.c:522
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:505
+#: option.c:523
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:506
+#: option.c:524
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:507
+#: option.c:525
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:508
+#: option.c:526
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:509
+#: option.c:527
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:510
+#: option.c:528
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:511
+#: option.c:529
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:512
+#: option.c:530
+msgid "Log debugging information."
+msgstr ""
+
+#: option.c:531
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:513
+#: option.c:532
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:514
+#: option.c:533
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:515
+#: option.c:534
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:516
+#: option.c:535
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:517
+#: option.c:536
 msgid "Enables DHCPv4 Rapid Commit option."
 msgstr ""
 
-#: option.c:518
+#: option.c:537
 msgid "Path to debug packet dump file"
 msgstr ""
 
-#: option.c:519
+#: option.c:538
 msgid "Mask which packets to dump"
 msgstr ""
 
-#: option.c:520
+#: option.c:539
 msgid "Call dhcp-script when lease expiry changes."
 msgstr ""
 
-#: option.c:725
+#: option.c:540
+msgid "Send Cisco Umbrella identifiers including remote IP."
+msgstr ""
+
+#: option.c:541
+msgid "Do not log routine TFTP."
+msgstr ""
+
+#: option.c:771
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -820,356 +853,397 @@ msgstr ""
 "Utilizare: dnsmasq [opţiuni]\n"
 "\n"
 
-#: option.c:727
+#: option.c:773
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Folosiţi opţiunile prescurtate doar în linie de comandă.\n"
 
-#: option.c:729
+#: option.c:775
 #, fuzzy, c-format
 msgid "Valid options are:\n"
 msgstr "Opţiunile valide sunt:\n"
 
-#: option.c:776 option.c:884
+#: option.c:822 option.c:933
 #, fuzzy
 msgid "bad address"
 msgstr "citesc %s - %d adrese"
 
-#: option.c:799 option.c:803
+#: option.c:847 option.c:851
 msgid "bad port"
 msgstr "port invalid"
 
-#: option.c:815 option.c:844 option.c:878
+#: option.c:864 option.c:893 option.c:927
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:839 option.c:873
+#: option.c:888 option.c:922
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:852 option.c:4042
+#: option.c:901 option.c:4362
 #, fuzzy
 msgid "bad interface name"
 msgstr "nume MX invalid"
 
-#: option.c:1184
+#: option.c:1192
+msgid "inappropriate vendor:"
+msgstr ""
+
+#: option.c:1199
+msgid "inappropriate encap:"
+msgstr ""
+
+#: option.c:1225
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
-#: option.c:1198
+#: option.c:1239
 msgid "bad dhcp-option"
 msgstr "dhcp-option invalid"
 
-#: option.c:1270
+#: option.c:1317
 #, fuzzy
 msgid "bad IP address"
 msgstr "citesc %s - %d adrese"
 
-#: option.c:1273 option.c:1412 option.c:3297
+#: option.c:1320 option.c:1459 option.c:3551
 #, fuzzy
 msgid "bad IPv6 address"
 msgstr "citesc %s - %d adrese"
 
-#: option.c:1366
+#: option.c:1413
 #, fuzzy
 msgid "bad IPv4 address"
 msgstr "citesc %s - %d adrese"
 
-#: option.c:1439 option.c:1533
+#: option.c:1486 option.c:1581
 msgid "bad domain in dhcp-option"
 msgstr "domeniu DNS invalid în declaraţia dhcp-option"
 
-#: option.c:1571
+#: option.c:1625
 msgid "dhcp-option too long"
 msgstr "declararea dhcp-option este prea lungă"
 
-#: option.c:1578
+#: option.c:1632
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1647
+#: option.c:1691
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1655
+#: option.c:1699
 msgid "illegal repeated keyword"
 msgstr ""
 
-#: option.c:1726 option.c:4764
+#: option.c:1770 option.c:5080
 #, fuzzy, c-format
 msgid "cannot access directory %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: option.c:1772 tftp.c:564 dump.c:68
+#: option.c:1816 tftp.c:566 dump.c:68
 #, fuzzy, c-format
 msgid "cannot access %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: option.c:1879
+#: option.c:1931
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1888
+#: option.c:1940
 msgid "bad log facility"
 msgstr ""
 
-#: option.c:1941
+#: option.c:1993
 msgid "bad MX preference"
 msgstr "preferinţă MX invalidă"
 
-#: option.c:1946
+#: option.c:1998
 msgid "bad MX name"
 msgstr "nume MX invalid"
 
-#: option.c:1960
+#: option.c:2012
 msgid "bad MX target"
 msgstr "ţintă MX invalidă"
 
-#: option.c:1980
+#: option.c:2032
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1984
+#: option.c:2036
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
-#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
+#: option.c:2291 option.c:2327
+#, fuzzy
+msgid "bad prefix length"
+msgstr "port invalid"
+
+#: option.c:2303 option.c:2348 option.c:2398
 #, fuzzy
 msgid "bad prefix"
 msgstr "port invalid"
 
-#: option.c:2658
+#: option.c:2418
+msgid "prefix length too small"
+msgstr ""
+
+#: option.c:2697
+#, fuzzy
+msgid "Bad address in --address"
+msgstr "adresa este folosită"
+
+#: option.c:2751
+#, fuzzy
+msgid "bad IPv4 prefix"
+msgstr "port invalid"
+
+#: option.c:2756 option.c:3569
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "port invalid"
+
+#: option.c:2777
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
-#: option.c:2871
+#: option.c:2843 option.c:2861
+msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+msgstr ""
+
+#: option.c:3119
 #, fuzzy
 msgid "bad port range"
 msgstr "port invalid"
 
-#: option.c:2897
+#: option.c:3145
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2941
+#: option.c:3189
 msgid "bad shared-network"
 msgstr ""
 
-#: option.c:2996
+#: option.c:3243
 msgid "only one tag allowed"
 msgstr ""
 
-#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
+#: option.c:3264 option.c:3280 option.c:3406 option.c:3414 option.c:3457
 msgid "bad dhcp-range"
 msgstr "dhcp-range invalid"
 
-#: option.c:3050
+#: option.c:3298
 msgid "inconsistent DHCP range"
 msgstr "domeniu DHCP inconsistent"
 
-#: option.c:3115
+#: option.c:3364
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:3117
+#: option.c:3366
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:3120
+#: option.c:3369
 msgid "prefix length must be at least 64"
 msgstr ""
 
-#: option.c:3123
+#: option.c:3372
 #, fuzzy
 msgid "inconsistent DHCPv6 range"
 msgstr "domeniu DHCP inconsistent"
 
-#: option.c:3142
+#: option.c:3391
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
-#: option.c:3262 option.c:3340
+#: option.c:3516 option.c:3594
 #, fuzzy
 msgid "bad hex constant"
 msgstr "dhcp-host invalid"
 
-#: option.c:3315
-#, fuzzy
-msgid "bad IPv6 prefix"
-msgstr "port invalid"
-
-#: option.c:3362
+#: option.c:3617
 #, fuzzy, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "adresă IP duplicat %s în declaraţia dhcp-config."
 
-#: option.c:3422
+#: option.c:3678
 #, fuzzy
 msgid "bad DHCP host name"
 msgstr "nume MX invalid"
 
-#: option.c:3508
+#: option.c:3764
 #, fuzzy
 msgid "bad tag-if"
 msgstr "ţintă MX invalidă"
 
-#: option.c:3851 option.c:4324
+#: option.c:4107 option.c:4623
 msgid "invalid port number"
 msgstr "număr de port invalid"
 
-#: option.c:3907
+#: option.c:4163
 #, fuzzy
 msgid "bad dhcp-proxy address"
 msgstr "citesc %s - %d adrese"
 
-#: option.c:3935
+#: option.c:4204
 #, fuzzy
 msgid "Bad dhcp-relay"
 msgstr "dhcp-range invalid"
 
-#: option.c:3979
+#: option.c:4248
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3989
+#: option.c:4258
 msgid "bad DUID"
 msgstr ""
 
-#: option.c:4023
+#: option.c:4292
 #, fuzzy
 msgid "missing address in alias"
 msgstr "adresa este folosită"
 
-#: option.c:4029
+#: option.c:4298
 #, fuzzy
 msgid "invalid alias range"
 msgstr "pondere invalidă"
 
-#: option.c:4081 option.c:4097
+#: option.c:4347
+#, fuzzy
+msgid "missing address in dynamic host"
+msgstr "adresa este folosită"
+
+#: option.c:4362
+#, fuzzy
+msgid "bad dynamic host"
+msgstr "nu pot citi %s: %s"
+
+#: option.c:4380 option.c:4396
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:4105
+#: option.c:4404
 msgid "duplicate CNAME"
 msgstr ""
 
-#: option.c:4132
+#: option.c:4431
 #, fuzzy
 msgid "bad PTR record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:4167
+#: option.c:4466
 #, fuzzy
 msgid "bad NAPTR record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:4203
+#: option.c:4502
 #, fuzzy
 msgid "bad RR record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:4236
+#: option.c:4535
 #, fuzzy
 msgid "bad CAA record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:4265
+#: option.c:4564
 msgid "bad TXT record"
 msgstr "înregistrare TXT invalidă"
 
-#: option.c:4308
+#: option.c:4607
 msgid "bad SRV record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:4315
+#: option.c:4614
 msgid "bad SRV target"
 msgstr "ţintă SRV invalidă"
 
-#: option.c:4334
+#: option.c:4633
 msgid "invalid priority"
 msgstr "prioritate invalidă"
 
-#: option.c:4339
+#: option.c:4638
 msgid "invalid weight"
 msgstr "pondere invalidă"
 
-#: option.c:4362
+#: option.c:4661
 #, fuzzy
 msgid "Bad host-record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:4402
+#: option.c:4700
 #, fuzzy
 msgid "Bad name in host-record"
 msgstr "nume invalid în %s"
 
-#: option.c:4444
+#: option.c:4742
 msgid "bad value for dnssec-check-unsigned"
 msgstr ""
 
-#: option.c:4480
+#: option.c:4778
 #, fuzzy
 msgid "bad trust anchor"
 msgstr "port invalid"
 
-#: option.c:4496
+#: option.c:4794
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4507
+#: option.c:4805
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
-#: option.c:4567
+#: option.c:4865
 msgid "missing \""
 msgstr "lipseşte \""
 
-#: option.c:4624
+#: option.c:4922
 msgid "bad option"
 msgstr "opţiune invalidă"
 
-#: option.c:4626
+#: option.c:4924
 msgid "extraneous parameter"
 msgstr "parametru nerecunoscut"
 
-#: option.c:4628
+#: option.c:4926
 msgid "missing parameter"
 msgstr "parametru lipsa"
 
-#: option.c:4630
+#: option.c:4928
 #, fuzzy
 msgid "illegal option"
 msgstr "opţiune invalidă"
 
-#: option.c:4637
+#: option.c:4935
 msgid "error"
 msgstr "eroare"
 
-#: option.c:4639
+#: option.c:4937
 #, fuzzy, c-format
 msgid " at line %d of %s"
 msgstr "%s la linia %d din %%s"
 
-#: option.c:4654 option.c:4939 option.c:4950
+#: option.c:4952 option.c:5229 option.c:5240
 #, fuzzy, c-format
 msgid "read %s"
 msgstr "citesc %s"
 
-#: option.c:4717 option.c:4840 tftp.c:754
+#: option.c:5015 option.c:5162 tftp.c:775
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: option.c:5027
+#: option.c:5316
 msgid "junk found in command line"
 msgstr ""
 
-#: option.c:5067
+#: option.c:5356
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "dnsmasq versiunea %s  %s\n"
 
-#: option.c:5068
+#: option.c:5357
 #, fuzzy, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1178,562 +1252,597 @@ msgstr ""
 "Opţiuni cu care a fost compilat %s\n"
 "\n"
 
-#: option.c:5069
+#: option.c:5358
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Acest program vine FĂRĂ NICI O GARANŢIE.\n"
 
-#: option.c:5070
+#: option.c:5359
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsmasq este un program gratuit, sunteţi invitaţi să-l redistribuiţi\n"
 
-#: option.c:5071
+#: option.c:5360
 #, fuzzy, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "în termenii Licenţei publice generale GNU, versiunea 2.\n"
 
-#: option.c:5088
+#: option.c:5377
 msgid "try --help"
 msgstr ""
 
-#: option.c:5090
+#: option.c:5379
 msgid "try -w"
 msgstr ""
 
-#: option.c:5092
+#: option.c:5381
 #, fuzzy, c-format
 msgid "bad command line options: %s"
 msgstr "opţiuni în linie de comandă invalide: %s."
 
-#: option.c:5161
+#: option.c:5450
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:5195
+#: option.c:5491
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "nu pot citi numele maşinii: %s"
 
-#: option.c:5223
+#: option.c:5519
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "se permite un singur fişier resolv.conf în modul no-poll"
 
-#: option.c:5233
+#: option.c:5529
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "am nevoie de un singur resolv.conf din care să citesc numele domeniului."
 
-#: option.c:5236 network.c:1594 dhcp.c:876
+#: option.c:5532 network.c:1670 dhcp.c:880
 #, fuzzy, c-format
 msgid "failed to read %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: option.c:5253
+#: option.c:5549
 #, c-format
 msgid "no search directive found in %s"
 msgstr "nu s-a găsit nici un criteriu de căutare în %s"
 
-#: option.c:5274
+#: option.c:5570
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:5283
+#: option.c:5579
 msgid "syntax check OK"
 msgstr ""
 
-#: forward.c:99
+#: forward.c:104
 #, fuzzy, c-format
 msgid "failed to send packet: %s"
 msgstr "ascultarea pe socket a eşuat: %s"
 
-#: forward.c:614
+#: forward.c:601
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:677
+#: forward.c:666
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "serverul DNS %s refuză interogările recursive"
 
-#: forward.c:709
+#: forward.c:702
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:961
+#: forward.c:1074
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1370 forward.c:1830
+#: forward.c:1381 forward.c:1910
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2321
+#: forward.c:2198
+#, fuzzy, c-format
+msgid "failed to bind server socket to %s: %s"
+msgstr "activarea socket-ului de ascultare pentru %s a eşuat: %s"
+
+#: forward.c:2494
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
 
-#: network.c:698
+#: forward.c:2496
+#, fuzzy, c-format
+msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
+
+#: network.c:670
+#, c-format
+msgid "stopped listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:867
 #, fuzzy, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "creearea socket-ului de ascultare a eşuat: %s"
 
-#: network.c:1002
+#: network.c:1148
+#, c-format
+msgid "listening on %s(#%d): %s port %d"
+msgstr ""
+
+#: network.c:1175
+#, fuzzy, c-format
+msgid "listening on %s port %d"
+msgstr "nu pot citi %s: %s"
+
+#: network.c:1208
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1009
+#: network.c:1215
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1018
+#: network.c:1224
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "atenţie: interfaţa %s nu există momentan"
 
-#: network.c:1027
+#: network.c:1233
 #, fuzzy, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "folosim adresele locale doar pentru %S %s"
 
-#: network.c:1085
+#: network.c:1291
 #, fuzzy, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "activarea socket-ului server-ului DHCP a eşuat: %s"
 
-#: network.c:1090
+#: network.c:1296
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1307
+#: network.c:1492
 #, fuzzy, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "activarea socket-ului de ascultare pentru %s a eşuat: %s"
 
-#: network.c:1499
+#: network.c:1569
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignorăm serverul DNS %s - interfaţă locală"
 
-#: network.c:1510
+#: network.c:1580
 #, fuzzy, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignorăm serverul DNS %s - nu pot creea/activa socket-ul: %s"
 
-#: network.c:1530
+#: network.c:1598
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1533
+#: network.c:1601
 msgid "unqualified"
 msgstr "invalid"
 
-#: network.c:1533
+#: network.c:1601
 msgid "names"
 msgstr ""
 
-#: network.c:1535
+#: network.c:1603
 msgid "default"
 msgstr ""
 
-#: network.c:1537
+#: network.c:1605
 msgid "domain"
 msgstr "domeniu"
 
-#: network.c:1543
+#: network.c:1607
 #, fuzzy, c-format
-msgid "using only locally-known addresses for %s %s"
-msgstr "folosim adresele locale doar pentru %S %s"
-
-#: network.c:1546
-#, fuzzy, c-format
-msgid "using standard nameservers for %s %s"
+msgid "using nameserver %s#%d for %s %s%s %s"
 msgstr "folosim serverul DNS %s#%d pentru %s %s"
 
-#: network.c:1548
-#, fuzzy, c-format
-msgid "using nameserver %s#%d for %s %s %s"
-msgstr "folosim serverul DNS %s#%d pentru %s %s"
-
-#: network.c:1552
+#: network.c:1611
 #, fuzzy, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "folosim serverul DNS %s#%d pentru %s %s"
 
-#: network.c:1555
+#: network.c:1614
 #, fuzzy, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "folosim serverul DNS %s#%d"
 
-#: network.c:1557
+#: network.c:1616
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "folosim serverul DNS %s#%d"
 
-#: network.c:1562
+#: network.c:1630
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s"
+msgstr "folosim adresele locale doar pentru %S %s"
+
+#: network.c:1633
+#, fuzzy, c-format
+msgid "using standard nameservers for %s"
+msgstr "folosim serverul DNS %s#%d pentru %s %s"
+
+#: network.c:1637
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "folosim serverul DNS %s#%d"
 
-#: network.c:1564
+#: network.c:1639
 #, fuzzy, c-format
 msgid "using %d more nameservers"
 msgstr "folosim serverul DNS %s#%d"
 
-#: dnsmasq.c:173
+#: dnsmasq.c:184
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:188
+#: dnsmasq.c:199
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:202
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:193
+#: dnsmasq.c:204
 #, fuzzy
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:199
+#: dnsmasq.c:210
 #, fuzzy
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:204
+#: dnsmasq.c:217
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
-#: dnsmasq.c:207
+#: dnsmasq.c:223
 #, fuzzy
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:212
+#: dnsmasq.c:228
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:217
+#: dnsmasq.c:233
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
-#: dnsmasq.c:222
+#: dnsmasq.c:238
 #, fuzzy
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:227
+#: dnsmasq.c:243
 #, fuzzy
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:232
+#: dnsmasq.c:248
 #, fuzzy
 msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:236
+#: dnsmasq.c:259
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:243
+#: dnsmasq.c:266
 msgid "--auth-server required when an auth zone is defined."
 msgstr ""
 
-#: dnsmasq.c:248
+#: dnsmasq.c:271
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:268
+#: dnsmasq.c:291
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:332
+#: dnsmasq.c:355
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
-#: dnsmasq.c:335
+#: dnsmasq.c:358
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "enumerarea interfeţelor a eşuat: %s"
 
-#: dnsmasq.c:344
+#: dnsmasq.c:367
 #, c-format
 msgid "unknown interface %s"
 msgstr "interfaţă necunoscută %s"
 
-#: dnsmasq.c:406
+#: dnsmasq.c:437
 #, fuzzy
 msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:416 dnsmasq.c:1171
+#: dnsmasq.c:445 dnsmasq.c:1207
 #, c-format
 msgid "DBus error: %s"
 msgstr "eroare DBus: %s"
 
-#: dnsmasq.c:419
+#: dnsmasq.c:448
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:429
+#: dnsmasq.c:456 dnsmasq.c:1228
+#, fuzzy, c-format
+msgid "UBus error: %s"
+msgstr "eroare DBus: %s"
+
+#: dnsmasq.c:459
 #, fuzzy
 msgid "UBus not available: set HAVE_UBUS in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:459
+#: dnsmasq.c:489
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:535
+#: dnsmasq.c:565
 #, c-format
 msgid "process is missing required capability %s"
 msgstr ""
 
-#: dnsmasq.c:567
+#: dnsmasq.c:597
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
-#: dnsmasq.c:815
+#: dnsmasq.c:845
 #, fuzzy, c-format
 msgid "started, version %s DNS disabled"
 msgstr "am pornit, versiunea %s memorie temporară dezactivată"
 
-#: dnsmasq.c:820
+#: dnsmasq.c:850
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "am ponit, versiunea %s memorie temporară %d"
 
-#: dnsmasq.c:822
+#: dnsmasq.c:852
 msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
 msgstr ""
 
-#: dnsmasq.c:825
+#: dnsmasq.c:855
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "am pornit, versiunea %s memorie temporară dezactivată"
 
-#: dnsmasq.c:828
+#: dnsmasq.c:858
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:831
+#: dnsmasq.c:861
 #, c-format
 msgid "compile time options: %s"
 msgstr "compilat cu opţiunile: %s"
 
-#: dnsmasq.c:840
+#: dnsmasq.c:870
 msgid "DBus support enabled: connected to system bus"
 msgstr "suportul DBus activ: sunt conectat la magistrala sistem"
 
-#: dnsmasq.c:842
+#: dnsmasq.c:872
 msgid "DBus support enabled: bus connection pending"
 msgstr "suportul DBus activ: aştept conexiunea la magistrală"
 
-#: dnsmasq.c:850
+#: dnsmasq.c:880
 #, fuzzy
 msgid "UBus support enabled: connected to system bus"
 msgstr "suportul DBus activ: sunt conectat la magistrala sistem"
 
-#: dnsmasq.c:852
+#: dnsmasq.c:882
 #, fuzzy
 msgid "UBus support enabled: bus connection pending"
 msgstr "suportul DBus activ: aştept conexiunea la magistrală"
 
-#: dnsmasq.c:872
+#: dnsmasq.c:902
 msgid "DNSSEC validation enabled but all unsigned answers are trusted"
 msgstr ""
 
-#: dnsmasq.c:874
+#: dnsmasq.c:904
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:878
+#: dnsmasq.c:908
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:881
+#: dnsmasq.c:911
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:884
+#: dnsmasq.c:914
 #, c-format
 msgid "configured with trust anchor for %s keytag %u"
 msgstr ""
 
 # for compatibility purposes the letters â, ă, ş, ţ and î can be written as their look-alike correspondent.
-#: dnsmasq.c:890
+#: dnsmasq.c:920
 #, fuzzy, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "încărcarea numelor din %s: %s a eşuat"
 
-#: dnsmasq.c:894
+#: dnsmasq.c:924
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "specific opţiunea --bind-interfaces din cauza limitărilor SO"
 
-#: dnsmasq.c:906
+#: dnsmasq.c:936
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "atenţie: interfaţa %s nu există momentan"
 
-#: dnsmasq.c:911
+#: dnsmasq.c:941
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
-#: dnsmasq.c:914
+#: dnsmasq.c:944
 #, fuzzy
 msgid "warning: no upstream servers configured"
 msgstr "configurăm serverele superioare prin Dbus"
 
-#: dnsmasq.c:918
+#: dnsmasq.c:948
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:939
+#: dnsmasq.c:969
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:944
+#: dnsmasq.c:974
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 msgid "root is "
 msgstr ""
 
-#: dnsmasq.c:958
+#: dnsmasq.c:991
 #, fuzzy
 msgid "enabled"
 msgstr "dezactivat"
 
-#: dnsmasq.c:960
+#: dnsmasq.c:993
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:961
+#: dnsmasq.c:994
 #, fuzzy
 msgid "single port mode"
 msgstr "număr de port invalid"
 
-#: dnsmasq.c:964
+#: dnsmasq.c:997
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:968
+#: dnsmasq.c:1001
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:994
+#: dnsmasq.c:1027
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
-#: dnsmasq.c:1173
+#: dnsmasq.c:1204
 msgid "connected to system DBus"
 msgstr "magistrala sistem Dbus conectată"
 
-#: dnsmasq.c:1345
+#: dnsmasq.c:1225
+#, fuzzy
+msgid "connected to system UBus"
+msgstr "magistrala sistem Dbus conectată"
+
+#: dnsmasq.c:1391
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
-#: dnsmasq.c:1349
+#: dnsmasq.c:1395
 #, fuzzy, c-format
 msgid "failed to create helper: %s"
 msgstr "nu pot citi %s: %s"
 
-#: dnsmasq.c:1353
+#: dnsmasq.c:1399
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
 # for compatibility purposes the letters â, ă, ş, ţ and î can be written as their look-alike correspondent.
-#: dnsmasq.c:1357
+#: dnsmasq.c:1403
 #, fuzzy, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "încărcarea numelor din %s: %s a eşuat"
 
 # for compatibility purposes the letters â, ă, ş, ţ and î can be written as their look-alike correspondent.
-#: dnsmasq.c:1361
+#: dnsmasq.c:1407
 #, fuzzy, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "încărcarea numelor din %s: %s a eşuat"
 
-#: dnsmasq.c:1365
+#: dnsmasq.c:1411
 #, fuzzy, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: dnsmasq.c:1369
+#: dnsmasq.c:1415
 #, fuzzy, c-format
 msgid "cannot open log %s: %s"
 msgstr "nu pot deschide %s:%s"
 
-#: dnsmasq.c:1373
+#: dnsmasq.c:1419
 #, fuzzy, c-format
 msgid "failed to load Lua script: %s"
 msgstr "nu pot încărca %s: %s"
 
-#: dnsmasq.c:1377
+#: dnsmasq.c:1423
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
-#: dnsmasq.c:1381
+#: dnsmasq.c:1427
 #, fuzzy, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "nu pot creea sau deschide fişierul cu împrumuturi: %s"
 
-#: dnsmasq.c:1465
+#: dnsmasq.c:1511
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1469
+#: dnsmasq.c:1515
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
-#: dnsmasq.c:1473
+#: dnsmasq.c:1519
 #, fuzzy, c-format
 msgid "failed to execute %s: %s"
 msgstr "accesarea serverului %s a eşuat: %s"
 
-#: dnsmasq.c:1513
+#: dnsmasq.c:1559
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
+#: dnsmasq.c:1594 dnssec.c:160 dnssec.c:204
 #, fuzzy, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: dnsmasq.c:1560
+#: dnsmasq.c:1606
 msgid "exiting on receipt of SIGTERM"
 msgstr "am primit SIGTERM, am terminat"
 
-#: dnsmasq.c:1588
+#: dnsmasq.c:1634
 #, fuzzy, c-format
 msgid "failed to access %s: %s"
 msgstr "accesarea serverului %s a eşuat: %s"
 
-#: dnsmasq.c:1618
+#: dnsmasq.c:1664
 #, c-format
 msgid "reading %s"
 msgstr "citesc %s"
 
-#: dnsmasq.c:1629
+#: dnsmasq.c:1675
 #, fuzzy, c-format
 msgid "no servers found in %s, will retry"
 msgstr "nu s-a găsit nici un criteriu de căutare în %s"
@@ -1778,27 +1887,27 @@ msgstr ""
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:471
+#: dhcp.c:473
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:526
+#: dhcp.c:530
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "domeniu DHCP %s -- %s nu este consistent cu masca de reţea %s"
 
-#: dhcp.c:914
+#: dhcp.c:918
 #, c-format
 msgid "bad line at %s line %d"
 msgstr "linie invalidă în %s rândul %d"
 
-#: dhcp.c:957
+#: dhcp.c:961
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1100 rfc3315.c:2139
+#: dhcp.c:1105 rfc3315.c:2182
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
@@ -1844,7 +1953,7 @@ msgstr ""
 
 #: lease.c:381
 #, fuzzy, c-format
-msgid "failed to write %s: %s (retry in %us)"
+msgid "failed to write %s: %s (retry in %u s)"
 msgstr "nu pot citi %s: %s"
 
 #: lease.c:955
@@ -1852,203 +1961,203 @@ msgstr "nu pot citi %s: %s"
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
-#: rfc2131.c:372
-#, c-format
-msgid "no address range available for DHCP request %s %s"
-msgstr "nici un domeniu de adrese disponibil pentru cererea DHCP %s %s"
-
-#: rfc2131.c:373
+#: rfc2131.c:378
 msgid "with subnet selector"
 msgstr "cu selectorul de subreţea"
 
-#: rfc2131.c:373
+#: rfc2131.c:383
 msgid "via"
 msgstr "prin"
 
-#: rfc2131.c:385
+#: rfc2131.c:389
+#, c-format
+msgid "no address range available for DHCP request %s %s"
+msgstr "nici un domeniu de adrese disponibil pentru cererea DHCP %s %s"
+
+#: rfc2131.c:403
 #, fuzzy, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "nici un domeniu de adrese disponibil pentru cererea DHCP %s %s"
 
-#: rfc2131.c:388 rfc3315.c:319
+#: rfc2131.c:409 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
-#: rfc2131.c:499
+#: rfc2131.c:521
 #, fuzzy, c-format
 msgid "%u vendor class: %s"
 msgstr "eroare DBus: %s"
 
-#: rfc2131.c:501
+#: rfc2131.c:523
 #, fuzzy, c-format
 msgid "%u user class: %s"
 msgstr "eroare DBus: %s"
 
-#: rfc2131.c:535
+#: rfc2131.c:557
 msgid "disabled"
 msgstr "dezactivat"
 
-#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
-#: rfc3315.c:1097
+#: rfc2131.c:598 rfc2131.c:1087 rfc2131.c:1532 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1121
 msgid "ignored"
 msgstr "ignorat"
 
-#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
+#: rfc2131.c:613 rfc2131.c:1333 rfc3315.c:867
 msgid "address in use"
 msgstr "adresa este folosită"
 
-#: rfc2131.c:605 rfc2131.c:1119
+#: rfc2131.c:627 rfc2131.c:1141
 msgid "no address available"
 msgstr "nici o adresă disponibilă"
 
-#: rfc2131.c:612 rfc2131.c:1273
+#: rfc2131.c:634 rfc2131.c:1295
 msgid "wrong network"
 msgstr "reţea greşită"
 
-#: rfc2131.c:627
+#: rfc2131.c:649
 msgid "no address configured"
 msgstr "adresă lipsă"
 
-#: rfc2131.c:633 rfc2131.c:1323
+#: rfc2131.c:655 rfc2131.c:1346
 msgid "no leases left"
 msgstr "nu mai am de unde să împrumut"
 
-#: rfc2131.c:734 rfc3315.c:499
+#: rfc2131.c:756 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:864
+#: rfc2131.c:885
 msgid "PXE BIS not supported"
 msgstr ""
 
-#: rfc2131.c:1032 rfc3315.c:1197
+#: rfc2131.c:1054 rfc3315.c:1222
 #, fuzzy, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "dezactivăm adresele DHCP statice %s"
 
-#: rfc2131.c:1053
+#: rfc2131.c:1075
 msgid "unknown lease"
 msgstr "împrumut necunoscut"
 
-#: rfc2131.c:1088
+#: rfc2131.c:1110
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1098
+#: rfc2131.c:1120
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1101
+#: rfc2131.c:1123
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1117 rfc2131.c:1316
+#: rfc2131.c:1139 rfc2131.c:1339
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1209
+#: rfc2131.c:1231
 msgid "wrong server-ID"
 msgstr ""
 
-#: rfc2131.c:1228
+#: rfc2131.c:1250
 msgid "wrong address"
 msgstr "adresă greşită"
 
-#: rfc2131.c:1246 rfc3315.c:961
+#: rfc2131.c:1268 rfc3315.c:975
 msgid "lease not found"
 msgstr "împrumutul nu a fost găsit"
 
-#: rfc2131.c:1281
+#: rfc2131.c:1303
 msgid "address not available"
 msgstr "adresă indisponibilă"
 
-#: rfc2131.c:1292
+#: rfc2131.c:1314
 msgid "static lease available"
 msgstr "împrumut static este disponibil"
 
-#: rfc2131.c:1296
+#: rfc2131.c:1318
 msgid "address reserved"
 msgstr "adresă rezervată"
 
-#: rfc2131.c:1304
+#: rfc2131.c:1327
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1845
+#: rfc2131.c:1866
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
-#: rfc2131.c:1854
+#: rfc2131.c:1875
 #, fuzzy, c-format
 msgid "%u server name: %s"
 msgstr "eroare DBus: %s"
 
-#: rfc2131.c:1862
+#: rfc2131.c:1885
 #, fuzzy, c-format
 msgid "%u next server: %s"
 msgstr "eroare DBus: %s"
 
-#: rfc2131.c:1865
+#: rfc2131.c:1889
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1928
+#: rfc2131.c:1952
 #, fuzzy, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "nu pot trimite opţiunea DHCP %d: nu mai este loc în pachet"
 
-#: rfc2131.c:2219
+#: rfc2131.c:2262
 msgid "PXE menu too large"
 msgstr ""
 
-#: rfc2131.c:2358 rfc3315.c:1470
+#: rfc2131.c:2425 rfc3315.c:1511
 #, fuzzy, c-format
 msgid "%u requested options: %s"
 msgstr "compilat cu opţiunile: %s"
 
-#: rfc2131.c:2675
+#: rfc2131.c:2742
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2738
+#: rfc2131.c:2805
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:76
+#: netlink.c:93
 #, fuzzy, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "nu pot să activez socket-ul netlink: %s"
 
-#: netlink.c:352
+#: netlink.c:377
 #, fuzzy, c-format
 msgid "netlink returns error: %s"
 msgstr "eroare DBus: %s"
 
-#: dbus.c:438
+#: dbus.c:434
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:443
+#: dbus.c:439
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:717
+#: dbus.c:713
 msgid "setting upstream servers from DBus"
 msgstr "configurăm serverele superioare prin Dbus"
 
-#: dbus.c:764
+#: dbus.c:760
 msgid "could not register a DBus message handler"
 msgstr "nu pot activa o interfaţă de mesaje DBus"
 
@@ -2075,31 +2184,36 @@ msgstr ""
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:347
+#: tftp.c:349
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:363
+#: tftp.c:365
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
-#: tftp.c:510
+#: tftp.c:512
 #, fuzzy, c-format
 msgid "file %s not found"
 msgstr "împrumutul nu a fost găsit"
 
-#: tftp.c:628
+#: tftp.c:602
+#, c-format
+msgid "ignoring packet from %s (TID mismatch)"
+msgstr ""
+
+#: tftp.c:646
 #, fuzzy, c-format
 msgid "failed sending %s to %s"
 msgstr "nu pot citi %s: %s"
 
-#: tftp.c:628
+#: tftp.c:646
 #, c-format
 msgid "sent %s to %s"
 msgstr ""
 
-#: tftp.c:678
+#: tftp.c:696
 #, c-format
 msgid "error %d %s received from %s"
 msgstr ""
@@ -2114,7 +2228,7 @@ msgstr ""
 msgid "log failed: %s"
 msgstr ""
 
-#: log.c:471
+#: log.c:477
 msgid "FAILED to start up"
 msgstr "pornirea A EŞUAT"
 
@@ -2168,11 +2282,11 @@ msgstr "nu exista interfaţă pentru adresa %s"
 msgid "address unavailable"
 msgstr "adresă indisponibilă"
 
-#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1272
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913 rfc3315.c:1047
 #, fuzzy
 msgid "no addresses available"
 msgstr "nici o adresă disponibilă"
@@ -2181,116 +2295,116 @@ msgstr "nici o adresă disponibilă"
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
+#: rfc3315.c:979 rfc3315.c:1180 rfc3315.c:1261
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1002
+#: rfc3315.c:1016
 msgid "deprecated"
 msgstr ""
 
-#: rfc3315.c:1007
+#: rfc3315.c:1023
 #, fuzzy
 msgid "address invalid"
 msgstr "adresa este folosită"
 
-#: rfc3315.c:1057 rfc3315.c:1059
+#: rfc3315.c:1081 rfc3315.c:1083
 msgid "confirm failed"
 msgstr ""
 
-#: rfc3315.c:1074
+#: rfc3315.c:1098
 #, fuzzy
 msgid "all addresses still on link"
 msgstr "adresă greşită în %s, linia %d"
 
-#: rfc3315.c:1165
+#: rfc3315.c:1189
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2130
+#: rfc3315.c:2173
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
-#: dhcp-common.c:145
+#: dhcp-common.c:154
 #, c-format
 msgid "Ignoring duplicate dhcp-option %d"
 msgstr ""
 
-#: dhcp-common.c:222
+#: dhcp-common.c:231
 #, c-format
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:444
+#: dhcp-common.c:451
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
-#: dhcp-common.c:478
+#: dhcp-common.c:485
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "adresă IP duplicat %s (%s) în declaraţia dhcp-config."
 
-#: dhcp-common.c:542
+#: dhcp-common.c:549
 #, fuzzy, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "configurarea SO_REUSEADDR pe socket-ul DHCP a eşuat: %s"
 
-#: dhcp-common.c:665
+#: dhcp-common.c:672
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:676
+#: dhcp-common.c:683
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:873
+#: dhcp-common.c:880
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:876
+#: dhcp-common.c:883
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:918
+#: dhcp-common.c:925
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
-#: dhcp-common.c:920
+#: dhcp-common.c:927
 #, fuzzy, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "DHCP, împrumuturi statice doar către  %.0s%s, timpul reînoirii %s"
 
-#: dhcp-common.c:922
+#: dhcp-common.c:929
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
-#: dhcp-common.c:923
+#: dhcp-common.c:930
 #, fuzzy, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "DHCP, domeniu IP %s -- %s, timpul reînoirii %s"
 
-#: dhcp-common.c:936
+#: dhcp-common.c:943
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:939
+#: dhcp-common.c:946
 #, fuzzy, c-format
 msgid "router advertisement on %s%s"
 msgstr "DHCP, împrumuturi statice doar către  %.0s%s, timpul reînoirii %s"
 
-#: dhcp-common.c:950
+#: dhcp-common.c:957
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:952
+#: dhcp-common.c:959
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2300,31 +2414,119 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "nu pot creea socket DHCP: %s"
 
-#: auth.c:439
+#: auth.c:464
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
 
-#: ipset.c:95
-#, fuzzy, c-format
-msgid "failed to find kernel version: %s"
-msgstr "activarea socket-ului server-ului DHCP a eşuat: %s"
-
-#: ipset.c:114
+#: ipset.c:99
 #, fuzzy, c-format
 msgid "failed to create IPset control socket: %s"
 msgstr "creearea socket-ului de ascultare a eşuat: %s"
 
-#: ipset.c:226
+#: ipset.c:211
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "nu pot citi %s: %s"
 
+#: pattern.c:29
+#, c-format
+msgid "[pattern.c:%d] Assertion failure: %s"
+msgstr ""
+
+#: pattern.c:142
+#, c-format
+msgid "Invalid DNS name: Invalid character %c."
+msgstr ""
+
+#: pattern.c:151
+msgid "Invalid DNS name: Empty label."
+msgstr ""
+
+#: pattern.c:156
+msgid "Invalid DNS name: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:170
+msgid "Invalid DNS name: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:176
+#, c-format
+msgid "Invalid DNS name: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:184
+#, c-format
+msgid "Invalid DNS name: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:189
+msgid "Invalid DNS name: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:199
+msgid "Invalid DNS name: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:204
+#, c-format
+msgid "DNS name has invalid length (%zu)."
+msgstr ""
+
+#: pattern.c:258
+#, c-format
+msgid "Invalid DNS name pattern: Invalid character %c."
+msgstr ""
+
+#: pattern.c:267
+msgid "Invalid DNS name pattern: Empty label."
+msgstr ""
+
+#: pattern.c:272
+msgid "Invalid DNS name pattern: Label starts with hyphen."
+msgstr ""
+
+#: pattern.c:285
+msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+msgstr ""
+
+#: pattern.c:295
+msgid "Invalid DNS name pattern: Label ends with hyphen."
+msgstr ""
+
+#: pattern.c:301
+#, c-format
+msgid "Invalid DNS name pattern: Label is too long (%zu)."
+msgstr ""
+
+#: pattern.c:309
+#, c-format
+msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+msgstr ""
+
+#: pattern.c:314
+msgid "Invalid DNS name pattern: Wildcard within final two labels."
+msgstr ""
+
+#: pattern.c:319
+msgid "Invalid DNS name pattern: Final label is fully numeric."
+msgstr ""
+
+#: pattern.c:329
+msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+msgstr ""
+
+#: pattern.c:334
+#, c-format
+msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
+msgstr ""
+
 #: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: dnssec.c:902
+#: dnssec.c:1014
 #, c-format
 msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
 msgstr ""
@@ -2356,7 +2558,7 @@ msgstr ""
 
 #: tables.c:101
 #, fuzzy, c-format
-msgid "IPset: error:%s"
+msgid "IPset: error: %s"
 msgstr "eroare DBus: %s"
 
 #: tables.c:108
@@ -2418,56 +2620,54 @@ msgstr "nu pot citi %s: %s"
 msgid "bad header in %s"
 msgstr "adresa este folosită"
 
-#: dump.c:201
+#: dump.c:205
 #, fuzzy
 msgid "failed to write packet dump"
 msgstr "ascultarea pe socket a eşuat: %s"
 
-#: dump.c:203
+#: dump.c:207
 #, c-format
 msgid "dumping UDP packet %u mask 0x%04x"
 msgstr ""
 
-#: ubus.c:52
+#: ubus.c:79
 #, c-format
 msgid "UBus subscription callback: %s subscriber(s)"
 msgstr ""
 
-#: ubus.c:73
+#: ubus.c:99
 #, fuzzy, c-format
 msgid "Cannot reconnect to UBus: %s"
 msgstr "nu pot deschide %s:%s"
 
-#: ubus.c:89
-msgid "Cannot initialize UBus: connection failed"
-msgstr ""
-
-#: ubus.c:102
-#, fuzzy, c-format
-msgid "Cannot add object to UBus: %s"
-msgstr "nu pot deschide %s:%s"
-
-#: ubus.c:112
-#, fuzzy
-msgid "Connected to system UBus"
-msgstr "magistrala sistem Dbus conectată"
-
-#: ubus.c:122
+#: ubus.c:135
 msgid "Cannot set UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:142
+#: ubus.c:155
 msgid "Cannot poll UBus listeners: no connection"
 msgstr ""
 
-#: ubus.c:155
+#: ubus.c:168
 msgid "Disconnecting from UBus"
 msgstr ""
 
-#: ubus.c:199
-#, fuzzy, c-format
-msgid "Failed to send UBus event: %s"
-msgstr "ascultarea pe socket a eşuat: %s"
+#: ubus.c:179 ubus.c:326
+#, c-format
+msgid "UBus command failed: %d (%s)"
+msgstr ""
+
+#: hash-questions.c:40
+msgid "Failed to create SHA-256 hash object"
+msgstr ""
+
+#, fuzzy
+#~ msgid "Cannot add object to UBus: %s"
+#~ msgstr "nu pot deschide %s:%s"
+
+#, fuzzy
+#~ msgid "Failed to send UBus event: %s"
+#~ msgstr "ascultarea pe socket a eşuat: %s"
 
 #~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
 #~ msgstr "incerc să configurez un server IPv6 prin Dbus - nu este suport IPv6"
index 3329d6d..1e4aad2 100644 (file)
--- a/src/arp.c
+++ b/src/arp.c
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -230,5 +230,3 @@ int do_arp_script_run(void)
 
   return 0;
 }
-
-
index b2fcd4b..172a4b2 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -105,7 +105,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
   int nameoffset, axfroffset = 0;
   int q, anscount = 0, authcount = 0;
   struct crec *crecp;
-  int  auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0;
+  int  auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0, out_of_zone = 0;
   struct auth_zone *zone = NULL;
   struct addrlist *subnet = NULL;
   char *cut;
@@ -146,6 +146,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
       if (qclass != C_IN)
        {
          auth = 0;
+         out_of_zone = 1;
          continue;
        }
 
@@ -159,6 +160,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
          
          if (!zone)
            {
+             out_of_zone = 1;
              auth = 0;
              continue;
            }
@@ -253,6 +255,17 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
                    
            } while ((crecp = cache_find_by_addr(crecp, &addr, now, flag)));
 
+         if (!found && is_rev_synth(flag, &addr, name) && (local_query || in_zone(zone, name, NULL)))
+           {
+             log_query(F_CONFIG | F_REVERSE | flag, name, &addr, NULL); 
+             found = 1;
+             
+             if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
+                                     daemon->auth_ttl, NULL,
+                                     T_PTR, C_IN, "d", name))
+               anscount++;
+           }
+
          if (found)
            nxdomain = 0;
          else
@@ -273,6 +286,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
          
          if (!zone)
            {
+             out_of_zone = 1;
              auth = 0;
              continue;
            }
@@ -400,6 +414,17 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
                       anscount++;
                   }
             }
+
+       if (!found && is_name_synthetic(flag, name, &addr) )
+        {
+          found = 1;
+          nxdomain = 0;
+          
+          log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
+          if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
+                                  daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addr))
+            anscount++;
+        }
        
       if (!cut)
        {
@@ -855,10 +880,22 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
     SET_RCODE(header, NXDOMAIN);
   else
     SET_RCODE(header, NOERROR); /* no error */
+  
   header->ancount = htons(anscount);
   header->nscount = htons(authcount);
   header->arcount = htons(0);
 
+  if (!local_query && out_of_zone)
+    {
+      SET_RCODE(header, REFUSED); 
+      header->ancount = htons(0);
+      header->nscount = htons(0);
+      addr.log.rcode = REFUSED;
+      addr.log.ede = EDE_NOT_AUTH;
+      log_query(F_UPSTREAM | F_RCODE, "error", &addr, NULL);
+      return resize_packet(header,  ansp - (unsigned char *)header, NULL, 0);
+    }
+  
   /* Advertise our packet size limit in our reply */
   if (have_pseudoheader)
     return add_pseudoheader(header,  ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
@@ -867,6 +904,3 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
 }
   
 #endif  
-  
-
-
index f33b28e..f7740b5 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -174,4 +174,3 @@ struct blockdata *blockdata_read(int fd, size_t len)
 {
   return blockdata_alloc_real(fd, NULL, len);
 }
-
index 0ac1c8f..15c42fc 100644 (file)
--- a/src/bpf.c
+++ b/src/bpf.c
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -440,5 +440,3 @@ void route_sock(void)
 }
 
 #endif /* HAVE_BSD_NETWORK */
-
-
index 2f2c519..8add610 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -488,8 +488,6 @@ struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class
   else
 #endif
     {
-      /* Don't log DNSSEC records here, done elsewhere */
-      log_query(flags | F_UPSTREAM, name, addr, NULL);
       if (daemon->max_cache_ttl != 0 && daemon->max_cache_ttl < ttl)
        ttl = daemon->max_cache_ttl;
       if (daemon->min_cache_ttl != 0 && daemon->min_cache_ttl > ttl)
@@ -1602,21 +1600,18 @@ int cache_make_stat(struct txt_record *t)
     case TXT_STAT_SERVERS:
       /* sum counts from different records for same server */
       for (serv = daemon->servers; serv; serv = serv->next)
-       serv->flags &= ~SERV_COUNTED;
+       serv->flags &= ~SERV_MARK;
       
       for (serv = daemon->servers; serv; serv = serv->next)
-       if (!(serv->flags & 
-             (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED | SERV_USE_RESOLV | SERV_NO_REBIND)))
+       if (!(serv->flags & SERV_MARK))
          {
            char *new, *lenp;
            int port, newlen, bytes_avail, bytes_needed;
            unsigned int queries = 0, failed_queries = 0;
            for (serv1 = serv; serv1; serv1 = serv1->next)
-             if (!(serv1->flags & 
-                   (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED | SERV_USE_RESOLV | SERV_NO_REBIND)) && 
-                 sockaddr_isequal(&serv->addr, &serv1->addr))
+             if (!(serv1->flags & SERV_MARK) && sockaddr_isequal(&serv->addr, &serv1->addr))
                {
-                 serv1->flags |= SERV_COUNTED;
+                 serv1->flags |= SERV_MARK;
                  queries += serv1->queries;
                  failed_queries += serv1->failed_queries;
                }
@@ -1644,6 +1639,7 @@ int cache_make_stat(struct txt_record *t)
          }
       t->txt = (unsigned char *)buff;
       t->len = p - buff;
+
       return 1;
     }
   
@@ -1686,27 +1682,24 @@ void dump_cache(time_t now)
 
   /* sum counts from different records for same server */
   for (serv = daemon->servers; serv; serv = serv->next)
-    serv->flags &= ~SERV_COUNTED;
+    serv->flags &= ~SERV_MARK;
   
   for (serv = daemon->servers; serv; serv = serv->next)
-    if (!(serv->flags & 
-         (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED | SERV_USE_RESOLV | SERV_NO_REBIND)))
+    if (!(serv->flags & SERV_MARK))
       {
        int port;
        unsigned int queries = 0, failed_queries = 0;
        for (serv1 = serv; serv1; serv1 = serv1->next)
-         if (!(serv1->flags & 
-               (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED | SERV_USE_RESOLV | SERV_NO_REBIND)) && 
-             sockaddr_isequal(&serv->addr, &serv1->addr))
+         if (!(serv1->flags & SERV_MARK) && sockaddr_isequal(&serv->addr, &serv1->addr))
            {
-             serv1->flags |= SERV_COUNTED;
+             serv1->flags |= SERV_MARK;
              queries += serv1->queries;
              failed_queries += serv1->failed_queries;
            }
        port = prettyprint_addr(&serv->addr, daemon->addrbuff);
        my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried or failed %u"), daemon->addrbuff, port, queries, failed_queries);
       }
-  
+
   if (option_bool(OPT_DEBUG) || option_bool(OPT_LOG))
     {
       struct crec *cache ;
@@ -1860,47 +1853,93 @@ char *querystr(char *desc, unsigned short type)
          if (types)
            sprintf(buff, "<%s>", types);
          else
-           sprintf(buff, "type=%d", type);
+           sprintf(buff, "<type=%d>", type);
        }
     }
   
   return buff ? buff : "";
 }
 
+static char *edestr(int ede)
+{
+  switch (ede)
+    {
+    case EDE_OTHER:                       return "other";
+    case EDE_USUPDNSKEY:                  return "unsupported DNSKEY algorithm";
+    case EDE_USUPDS:                      return "unsupported DS digest";
+    case EDE_STALE:                       return "stale answer";
+    case EDE_FORGED:                      return "forged";
+    case EDE_DNSSEC_IND:                  return "DNSSEC indeterminate";
+    case EDE_DNSSEC_BOGUS:                return "DNSSEC bogus";
+    case EDE_SIG_EXP:                     return "DNSSEC signature expired";
+    case EDE_SIG_NYV:                     return "DNSSEC sig not yet valid";
+    case EDE_NO_DNSKEY:                   return "DNSKEY missing";
+    case EDE_NO_RRSIG:                    return "RRSIG missing";
+    case EDE_NO_ZONEKEY:                  return "no zone key bit set";
+    case EDE_NO_NSEC:                     return "NSEC(3) missing";
+    case EDE_CACHED_ERR:                  return "cached error";
+    case EDE_NOT_READY:                   return "not ready";
+    case EDE_BLOCKED:                     return "blocked";
+    case EDE_CENSORED:                    return "censored";
+    case EDE_FILTERED:                    return "filtered";
+    case EDE_PROHIBITED:                  return "prohibited";
+    case EDE_STALE_NXD:                   return "stale NXDOMAIN";
+    case EDE_NOT_AUTH:                    return "not authoritative";
+    case EDE_NOT_SUP:                     return "not supported";
+    case EDE_NO_AUTH:                     return "no reachable authority";
+    case EDE_NETERR:                      return "network error";
+    case EDE_INVALID_DATA:                return "invalid data";
+    default:                              return "unknown";
+    }
+}
+
 void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
 {
-  char *source, *dest = daemon->addrbuff;
+  char *source, *dest = arg;
   char *verb = "is";
+  char *extra = "";
   
   if (!option_bool(OPT_LOG))
     return;
+  
+#ifdef HAVE_DNSSEC
+  if ((flags & F_DNSSECOK) && option_bool(OPT_EXTRALOG))
+    extra = " (DNSSEC signed)";
+#endif
 
   name = sanitise(name);
 
   if (addr)
     {
+      dest = daemon->addrbuff;
+
       if (flags & F_KEYTAG)
        sprintf(daemon->addrbuff, arg, addr->log.keytag, addr->log.algo, addr->log.digest);
       else if (flags & F_RCODE)
        {
          unsigned int rcode = addr->log.rcode;
 
-          if (rcode == SERVFAIL)
-            dest = "SERVFAIL";
-          else if (rcode == REFUSED)
-            dest = "REFUSED";
-          else if (rcode == NOTIMP)
-            dest = "not implemented";
-          else
-            sprintf(daemon->addrbuff, "%u", rcode);
+         if (rcode == SERVFAIL)
+           dest = "SERVFAIL";
+         else if (rcode == REFUSED)
+           dest = "REFUSED";
+         else if (rcode == NOTIMP)
+           dest = "not implemented";
+         else
+           sprintf(daemon->addrbuff, "%u", rcode);
+
+         if (addr->log.ede != EDE_UNSET)
+           {
+             extra = daemon->addrbuff;
+             sprintf(extra, " (EDE: %s)", edestr(addr->log.ede));
+           }
        }
-      else
+      else if (flags & (F_IPV4 | F_IPV6))
        inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
                  addr, daemon->addrbuff, ADDRSTRLEN);
-      
+      else
+       dest = arg;
     }
-  else
-    dest = arg;
 
   if (flags & F_REVERSE)
     {
@@ -1938,7 +1977,15 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
   else if (flags & F_UPSTREAM)
     source = "reply";
   else if (flags & F_SECSTAT)
-    source = "validation";
+    {
+      if (addr && addr->log.ede != EDE_UNSET && option_bool(OPT_EXTRALOG))
+       {
+         extra = daemon->addrbuff;
+         sprintf(extra, " (EDE: %s)", edestr(addr->log.ede));
+       }
+      source = "validation";
+      dest = arg;
+    }
   else if (flags & F_AUTH)
     source = "auth";
   else if (flags & F_SERVER)
@@ -1971,14 +2018,14 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
 
   if (option_bool(OPT_EXTRALOG))
     {
-      int port = prettyprint_addr(daemon->log_source_addr, daemon->addrbuff2);
       if (flags & F_NOEXTRA)
-       my_syslog(LOG_INFO, "* %s/%u %s %s %s %s", daemon->addrbuff2, port, source, name, verb, dest);
+       my_syslog(LOG_INFO, "%u %s %s %s %s%s", daemon->log_display_id, source, name, verb, dest, extra);
       else
-       my_syslog(LOG_INFO, "%u %s/%u %s %s %s %s", daemon->log_display_id, daemon->addrbuff2, port, source, name, verb, dest);
+       {
+          int port = prettyprint_addr(daemon->log_source_addr, daemon->addrbuff2);
+          my_syslog(LOG_INFO, "%u %s/%u %s %s %s %s%s", daemon->log_display_id, daemon->addrbuff2, port, source, name, verb, dest, extra);
+       }
     }
   else
-    my_syslog(LOG_INFO, "%s %s %s %s", source, name, verb, dest);
+    my_syslog(LOG_INFO, "%s %s %s %s%s", source, name, verb, dest, extra);
 }
-
index e71a117..30e23d8 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #define SAFE_PKTSZ 1280 /* "go anywhere" UDP packet size */
 #define KEYBLOCK_LEN 40 /* choose to minimise fragmentation when storing DNSSEC keys */
 #define DNSSEC_WORK 50 /* Max number of queries to validate one question */
-#define TIMEOUT 10 /* drop UDP queries after TIMEOUT seconds */
+#define TIMEOUT 10     /* drop UDP queries after TIMEOUT seconds */
 #define FORWARD_TEST 50 /* try all servers every 50 queries */
 #define FORWARD_TIME 20 /* or 20 seconds */
 #define UDP_TEST_TIME 60 /* How often to reset our idea of max packet size. */
 #define SERVERS_LOGGED 30 /* Only log this many servers when logging state */
 #define LOCALS_LOGGED 8 /* Only log this many local addresses when logging state */
-#define RANDOM_SOCKS 64 /* max simultaneous random ports */
 #define LEASE_RETRY 60 /* on error, retry writing leasefile after LEASE_RETRY seconds */
 #define CACHESIZ 150 /* default cache size */
 #define TTL_FLOOR_LIMIT 3600 /* don't allow --min-cache-ttl to raise TTL above this under any circumstances */
@@ -120,8 +119,8 @@ HAVE_AUTH
    define this to include the facility to act as an authoritative DNS
    server for one or more zones.
 
-HAVE_NETTLEHASH
-   include just hash function from nettle, but no DNSSEC.
+HAVE_CRYPTOHASH
+   include just hash function from crypto library, but no DNSSEC.
 
 HAVE_DNSSEC
    include DNSSEC validator.
@@ -144,6 +143,7 @@ NO_SCRIPT
 NO_LARGEFILE
 NO_AUTH
 NO_DUMPFILE
+NO_LOOP
 NO_INOTIFY
    these are available to explicitly disable compile time options which would 
    otherwise be enabled automatically or which are enabled  by default 
@@ -190,7 +190,7 @@ RESOLVFILE
 /* #define HAVE_IDN */
 /* #define HAVE_LIBIDN2 */
 /* #define HAVE_CONNTRACK */
-/* #define HAVE_NETTLEHASH */
+/* #define HAVE_CRYPTOHASH */
 /* #define HAVE_DNSSEC */
 
 
@@ -424,10 +424,10 @@ static char *compile_opts =
 "no-"
 #endif
 "auth "
-#if !defined(HAVE_NETTLEHASH) && !defined(HAVE_DNSSEC)
+#if !defined(HAVE_CRYPTOHASH) && !defined(HAVE_DNSSEC)
 "no-"
 #endif
-"nettlehash "
+"cryptohash "
 #ifndef HAVE_DNSSEC
 "no-"
 #endif
@@ -448,7 +448,4 @@ static char *compile_opts =
 #endif
 "dumpfile";
 
-#endif
-
-
-
+#endif /* defined(HAVE_DHCP) */
index 33f5ceb..745a2a3 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -82,7 +82,4 @@ static int callback(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, vo
   return NFCT_CB_CONTINUE;
 }
 
-#endif
-  
-
-
+#endif /* HAVE_CONNTRACK */
index 09525d2..4009569 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #include "dnsmasq.h"
 
-#ifdef HAVE_DNSSEC
+#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH)
 
+/* Minimal version of nettle */
+
+/* bignum.h includes version.h and works on
+   earlier releases of nettle which don't have version.h */
+#include <nettle/bignum.h>
+#if !defined(NETTLE_VERSION_MAJOR)
+#  define NETTLE_VERSION_MAJOR 2
+#  define NETTLE_VERSION_MINOR 0
+#endif
+#define MIN_VERSION(major, minor) ((NETTLE_VERSION_MAJOR == (major) && NETTLE_VERSION_MINOR >= (minor)) || \
+                                  (NETTLE_VERSION_MAJOR > (major)))
+
+#endif /* defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH) */
+
+#if defined(HAVE_DNSSEC)
 #include <nettle/rsa.h>
 #include <nettle/ecdsa.h>
 #include <nettle/ecc-curve.h>
+#if MIN_VERSION(3, 1)
 #include <nettle/eddsa.h>
-#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
-#  include <nettle/gostdsa.h>
 #endif
+#if MIN_VERSION(3, 6)
+#  include <nettle/gostdsa.h>
 #endif
 
-#if defined(HAVE_DNSSEC) || defined(HAVE_NETTLEHASH)
-#include <nettle/nettle-meta.h>
-#include <nettle/bignum.h>
-
+#if MIN_VERSION(3, 1)
 /* Implement a "hash-function" to the nettle API, which simply returns
    the input data, concatenated into a single, statically maintained, buffer.
 
@@ -84,7 +97,6 @@ static void null_hash_update(void *ctxv, size_t length, const uint8_t *src)
   ctx->len += length;
 }
  
-
 static void null_hash_digest(void *ctx, size_t length, uint8_t *dst)
 {
   (void)length;
@@ -103,35 +115,7 @@ static struct nettle_hash null_hash = {
   (nettle_hash_digest_func *) null_hash_digest
 };
 
-/* Find pointer to correct hash function in nettle library */
-const struct nettle_hash *hash_find(char *name)
-{
-  if (!name)
-    return NULL;
-  
-  /* We provide a "null" hash which returns the input data as digest. */
-  if (strcmp(null_hash.name, name) == 0)
-    return &null_hash;
-
-  /* libnettle >= 3.4 provides nettle_lookup_hash() which avoids nasty ABI
-     incompatibilities if sizeof(nettle_hashes) changes between library
-     versions. It also #defines nettle_hashes, so use that to tell
-     if we have the new facilities. */
-  
-#ifdef nettle_hashes
-  return nettle_lookup_hash(name);
-#else
-  {
-    int i;
-
-    for (i = 0; nettle_hashes[i]; i++)
-      if (strcmp(nettle_hashes[i]->name, name) == 0)
-       return nettle_hashes[i];
-  }
-  
-  return NULL;
-#endif
-}
+#endif /* MIN_VERSION(3, 1) */
 
 /* expand ctx and digest memory allocations if necessary and init hash function */
 int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **digestp)
@@ -171,10 +155,6 @@ int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **diges
   return 1;
 }
 
-#endif
-
-#ifdef HAVE_DNSSEC
-  
 static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
                              unsigned char *digest, size_t digest_len, int algo)
 {
@@ -238,7 +218,7 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
   static struct ecc_point *key_256 = NULL, *key_384 = NULL;
   static mpz_t x, y;
   static struct dsa_signature *sig_struct;
-#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR < 4
+#if !MIN_VERSION(3, 4)
 #define nettle_get_secp_256r1() (&nettle_secp_256r1)
 #define nettle_get_secp_384r1() (&nettle_secp_384r1)
 #endif
@@ -301,7 +281,7 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
   return nettle_ecdsa_verify(key, digest_len, digest, sig_struct);
 }
 
-#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
+#if MIN_VERSION(3, 6)
 static int dnsmasq_gostdsa_verify(struct blockdata *key_data, unsigned int key_len, 
                                  unsigned char *sig, size_t sig_len,
                                  unsigned char *digest, size_t digest_len, int algo)
@@ -342,6 +322,7 @@ static int dnsmasq_gostdsa_verify(struct blockdata *key_data, unsigned int key_l
 }
 #endif
 
+#if MIN_VERSION(3, 1)
 static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len, 
                                unsigned char *sig, size_t sig_len,
                                unsigned char *digest, size_t digest_len, int algo)
@@ -368,7 +349,7 @@ static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len
                                   ((struct null_hash_digest *)digest)->buff,
                                   sig);
       
-#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
+#if MIN_VERSION(3, 6)
     case 16:
       if (key_len != ED448_KEY_SIZE ||
          sig_len != ED448_SIGNATURE_SIZE)
@@ -384,6 +365,7 @@ static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len
 
   return 0;
 }
+#endif
 
 static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
                             unsigned char *digest, size_t digest_len, int algo)
@@ -399,16 +381,18 @@ static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key
     case 5: case 7: case 8: case 10:
       return dnsmasq_rsa_verify;
 
-#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
+#if MIN_VERSION(3, 6)
     case 12:
       return dnsmasq_gostdsa_verify;
 #endif
       
     case 13: case 14:
       return dnsmasq_ecdsa_verify;
-
+      
+#if MIN_VERSION(3, 1)
     case 15: case 16:
       return dnsmasq_eddsa_verify;
+#endif
     }
   
   return NULL;
@@ -479,4 +463,37 @@ char *nsec3_digest_name(int digest)
     }
 }
 
+#endif /* defined(HAVE_DNSSEC) */
+
+#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH)
+/* Find pointer to correct hash function in nettle library */
+const struct nettle_hash *hash_find(char *name)
+{
+  if (!name)
+    return NULL;
+  
+#if MIN_VERSION(3,1) && defined(HAVE_DNSSEC)
+  /* We provide a "null" hash which returns the input data as digest. */
+  if (strcmp(null_hash.name, name) == 0)
+    return &null_hash;
 #endif
+  
+  /* libnettle >= 3.4 provides nettle_lookup_hash() which avoids nasty ABI
+     incompatibilities if sizeof(nettle_hashes) changes between library
+     versions. */
+#if MIN_VERSION(3, 4)
+  return nettle_lookup_hash(name);
+#else
+  {
+    int i;
+
+    for (i = 0; nettle_hashes[i]; i++)
+      if (strcmp(nettle_hashes[i]->name, name) == 0)
+       return nettle_hashes[i];
+  }
+  
+  return NULL;
+#endif
+}
+
+#endif /* defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH) */
index 6def129..cbdce9c 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -215,7 +215,7 @@ static void dbus_read_servers(DBusMessage *message)
          domain = NULL;
        
        if (!skip)
-         add_update_server(SERV_FROM_DBUS, &addr, &source_addr, NULL, domain);
+         add_update_server(SERV_FROM_DBUS, &addr, &source_addr, NULL, domain, NULL);
      
       } while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING); 
     }
@@ -276,7 +276,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
     {
       const char *str = NULL;
       union  mysockaddr addr, source_addr;
-      int flags = 0;
+      u16 flags = 0;
       char interface[IF_NAMESIZE];
       char *str_addr, *str_domain = NULL;
 
@@ -361,10 +361,6 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
          strcpy(str_addr, str);
        }
 
-      memset(&addr, 0, sizeof(addr));
-      memset(&source_addr, 0, sizeof(source_addr));
-      memset(&interface, 0, sizeof(interface));
-
       /* parse the IP address */
       if ((addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, &flags)))
        {
@@ -377,7 +373,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
       /* 0.0.0.0 for server address == NULL, for Dbus */
       if (addr.in.sin_family == AF_INET &&
           addr.in.sin_addr.s_addr == 0)
-        flags |= SERV_NO_ADDR;
+        flags |= SERV_LITERAL_ADDRESS;
       
       if (strings)
        {
@@ -392,7 +388,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
            else 
              p = NULL;
            
-           add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain);
+           add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain, NULL);
          } while ((str_domain = p));
        }
       else
@@ -407,7 +403,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
              dbus_message_iter_get_basic(&string_iter, &str);
            dbus_message_iter_next (&string_iter);
            
-           add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str);
+           add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str, NULL);
          } while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
        }
         
@@ -416,7 +412,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
     }
 
   cleanup_servers();
-
+    
   if (dup)
     free(dup);
 
@@ -715,7 +711,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
   if (new_servers)
     {
       my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
-      check_servers();
+      check_servers(0);
       if (option_bool(OPT_RELOAD))
        clear_cache = 1;
     }
index eae9886..1f91ca0 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -79,13 +79,46 @@ ssize_t recv_dhcp_packet(int fd, struct msghdr *msg)
   return (msg->msg_flags & MSG_TRUNC) ? -1 : new_sz;
 }
 
+/* like match_netid() except that the check can have a trailing * for wildcard */
+/* started as a direct copy of match_netid() */
+int match_netid_wild(struct dhcp_netid *check, struct dhcp_netid *pool)
+{
+  struct dhcp_netid *tmp1;
+  
+  for (; check; check = check->next)
+    {
+      const int check_len = strlen(check->net);
+      const int is_wc = (check->net[check_len - 1] == '*');
+      
+      /* '#' for not is for backwards compat. */
+      if (check->net[0] != '!' && check->net[0] != '#')
+       {
+         for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
+           if (is_wc ? (strncmp(check->net, tmp1->net, check_len-1) == 0) :
+               (strcmp(check->net, tmp1->net) == 0))
+             break;
+         if (!tmp1)
+           return 0;
+       }
+      else
+       for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
+         if (is_wc ? (strncmp((check->net)+1, tmp1->net, check_len-2) == 0) :
+             (strcmp((check->net)+1, tmp1->net) == 0))
+           return 0;
+    }
+  return 1;
+}
+
 struct dhcp_netid *run_tag_if(struct dhcp_netid *tags)
 {
   struct tag_if *exprs;
   struct dhcp_netid_list *list;
 
+  /* this now uses match_netid_wild() above so that tag_if can
+   * be used to set a 'group of interfaces' tag.
+   */
   for (exprs = daemon->tag_if; exprs; exprs = exprs->next)
-    if (match_netid(exprs->tag, tags, 1))
+    if (match_netid_wild(exprs->tag, tags))
       for (list = exprs->set; list; list = list->next)
        {
          list->list->next = tags;
@@ -280,31 +313,29 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config
 {
   if (!context) /* called via find_config() from lease_update_from_configs() */
     return 1; 
+
+  if (!(config->flags & (CONFIG_ADDR | CONFIG_ADDR6)))
+    return 1;
   
 #ifdef HAVE_DHCP6
   if (context->flags & CONTEXT_V6)
     {
        struct addrlist *addr_list;
 
-       if (!(config->flags & CONFIG_ADDR6))
-        return 1;
-       
-        for (; context; context = context->current)
-         for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
-           {
-             if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
-               return 1;
-             
-             if (is_same_net6(&addr_list->addr.addr6, &context->start6, context->prefix))
-               return 1;
-           }
+       if (config->flags & CONFIG_ADDR6)
+        for (; context; context = context->current)
+          for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
+            {
+              if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
+                return 1;
+              
+              if (is_same_net6(&addr_list->addr.addr6, &context->start6, context->prefix))
+                return 1;
+            }
     }
   else
 #endif
     {
-      if (!(config->flags & CONFIG_ADDR))
-       return 1;
-      
       for (; context; context = context->current)
        if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))
          return 1;
@@ -622,6 +653,8 @@ static const struct opttab_t {
   { "client-arch", 93, 2 | OT_DEC },
   { "client-interface-id", 94, 0 },
   { "client-machine-id", 97, 0 },
+  { "posix-timezone", 100, OT_NAME }, /* RFC 4833, Sec. 2 */
+  { "tzdb-timezone", 101, OT_NAME }, /* RFC 4833, Sec. 2 */
   { "subnet-select", 118, OT_INTERNAL },
   { "domain-search", 119, OT_RFC1035_NAME },
   { "sip-server", 120, 0 },
index e9007c8..6ff3ffa 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
index bea4688..e500bc2 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -468,8 +468,11 @@ void dhcp_packet(time_t now, int pxe_fd)
 
   /* This can fail when, eg, iptables DROPS destination 255.255.255.255 */
   if (errno != 0)
-    my_syslog(MS_DHCP | LOG_WARNING, _("Error sending DHCP packet to %s: %s"),
-             inet_ntoa(dest.sin_addr), strerror(errno));
+    {
+      inet_ntop(AF_INET, &dest.sin_addr, daemon->addrbuff, ADDRSTRLEN);
+      my_syslog(MS_DHCP | LOG_WARNING, _("Error sending DHCP packet to %s: %s"),
+               daemon->addrbuff, strerror(errno));
+    }
 }
 
 /* check against secondary interface addresses */
@@ -521,10 +524,11 @@ static void guess_range_netmask(struct in_addr addr, struct in_addr netmask)
            !(is_same_net(addr, context->start, netmask) &&
              is_same_net(addr, context->end, netmask)))
          {
-           strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
-           strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
+           inet_ntop(AF_INET, &context->start, daemon->dhcp_buff, DHCP_BUFF_SZ);
+           inet_ntop(AF_INET, &context->end, daemon->dhcp_buff2, DHCP_BUFF_SZ);
+           inet_ntop(AF_INET, &netmask, daemon->addrbuff, ADDRSTRLEN);
            my_syslog(MS_DHCP | LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
-                     daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
+                     daemon->dhcp_buff, daemon->dhcp_buff2, daemon->addrbuff);
          }     
        context->netmask = netmask;
       }
@@ -922,7 +926,7 @@ void dhcp_read_ethers(void)
       
       if (!*cp)
        {
-         if ((addr.s_addr = inet_addr(ip)) == (in_addr_t)-1)
+         if (inet_pton(AF_INET, ip, &addr.s_addr) < 1)
            {
              my_syslog(MS_DHCP | LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno); 
              continue;
@@ -1097,7 +1101,8 @@ static int  relay_upstream4(struct dhcp_relay *relay, struct dhcp_packet *mess,
       if (option_bool(OPT_LOG_OPTS))
        {
          inet_ntop(AF_INET, &relay->local, daemon->addrbuff, ADDRSTRLEN);
-         my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay %s -> %s"), daemon->addrbuff, inet_ntoa(relay->server.addr4));
+         inet_ntop(AF_INET, &relay->server.addr4, daemon->dhcp_buff2, DHCP_BUFF_SZ);
+         my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay %s -> %s"), daemon->addrbuff, daemon->dhcp_buff2);
        }
       
       /* Save this for replies */
index 48b027b..ebe8dfd 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -72,4 +72,3 @@
 #define DHCP6NOBINDING   3
 #define DHCP6NOTONLINK   4
 #define DHCP6USEMULTI    5
-
index 096e2e1..2be877f 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -825,6 +825,4 @@ void dhcp_construct_contexts(time_t now)
     }
 }
 
-#endif
-
-
+#endif /* HAVE_DHCP6 */
index 8edb9f3..496a4bb 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #define EDNS0_OPTION_MAC            65001 /* dyndns.org temporary assignment */
 #define EDNS0_OPTION_CLIENT_SUBNET  8     /* IANA */
+#define EDNS0_OPTION_EDE            15    /* IANA - RFC 8914 */
 #define EDNS0_OPTION_NOMDEVICEID    65073 /* Nominum temporary assignment */
 #define EDNS0_OPTION_NOMCPEID       65074 /* Nominum temporary assignment */
+#define EDNS0_OPTION_UMBRELLA       20292 /* Cisco Umbrella temporary assignment */
+
+/* RFC-8914 extended errors, negative values are our definitions */
+#define EDE_UNSET          -1  /* No extended DNS error available */
+#define EDE_OTHER           0  /* Other */
+#define EDE_USUPDNSKEY      1  /* Unsupported DNSKEY algo */
+#define EDE_USUPDS          2  /* Unsupported DS Digest */
+#define EDE_STALE           3  /* Stale answer */
+#define EDE_FORGED          4  /* Forged answer */
+#define EDE_DNSSEC_IND      5  /* DNSSEC Indeterminate  */
+#define EDE_DNSSEC_BOGUS    6  /* DNSSEC Bogus */
+#define EDE_SIG_EXP         7  /* Signature Expired */
+#define EDE_SIG_NYV         8  /* Signature Not Yet Valid  */
+#define EDE_NO_DNSKEY       9  /* DNSKEY missing */
+#define EDE_NO_RRSIG       10  /* RRSIGs missing */
+#define EDE_NO_ZONEKEY     11  /* No Zone Key Bit Set */
+#define EDE_NO_NSEC        12  /* NSEC Missing  */
+#define EDE_CACHED_ERR     13  /* Cached Error */
+#define EDE_NOT_READY      14  /* Not Ready */
+#define EDE_BLOCKED        15  /* Blocked */
+#define EDE_CENSORED       16  /* Censored */
+#define EDE_FILTERED       17  /* Filtered */
+#define EDE_PROHIBITED     18  /* Prohibited */
+#define EDE_STALE_NXD      19  /* Stale NXDOMAIN */
+#define EDE_NOT_AUTH       20  /* Not Authoritative */
+#define EDE_NOT_SUP        21  /* Not Supported */
+#define EDE_NO_AUTH        22  /* No Reachable Authority */
+#define EDE_NETERR         23  /* Network error */
+#define EDE_INVALID_DATA   24  /* Invalid Data */
+
+
+
 
 struct dns_header {
   u16 id;
index 2306c48..602daed 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@ struct daemon *daemon;
 static volatile pid_t pid = 0;
 static volatile int pipewrite;
 
-static int set_dns_listeners(time_t now);
+static void set_dns_listeners(void);
 static void check_dns_listeners(time_t now);
 static void sig_handler(int sig);
 static void async_event(int pipe, time_t now);
@@ -109,7 +109,6 @@ int main (int argc, char **argv)
   daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
   daemon->packet = safe_malloc(daemon->packet_buff_sz);
   
-  daemon->addrbuff = safe_malloc(ADDRSTRLEN);
   if (option_bool(OPT_EXTRALOG))
     daemon->addrbuff2 = safe_malloc(ADDRSTRLEN);
   
@@ -135,6 +134,13 @@ int main (int argc, char **argv)
     }
 #endif
 
+#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
+  /* CONNTRACK UBUS code uses this buffer, so if not allocated above,
+     we need to allocate it here. */
+  if (option_bool(OPT_CMARK_ALST_EN) && !daemon->workspacename)
+    daemon->workspacename = safe_malloc(MAXDNAME);
+#endif
+  
 #ifdef HAVE_DHCP
   if (!daemon->lease_file)
     {
@@ -205,8 +211,13 @@ int main (int argc, char **argv)
 #endif
 
 #ifdef HAVE_CONNTRACK
-  if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
-    die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF); 
+  if (option_bool(OPT_CONNTRACK))
+    {
+      if (daemon->query_port != 0 || daemon->osport)
+       die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
+
+      need_cap_net_admin = 1;
+    }
 #else
   if (option_bool(OPT_CONNTRACK))
     die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
@@ -237,9 +248,16 @@ int main (int argc, char **argv)
     die(_("Ubus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
 #endif
   
+  /* Handle only one of min_port/max_port being set. */
+  if (daemon->min_port != 0 && daemon->max_port == 0)
+    daemon->max_port = MAX_PORT;
+  
+  if (daemon->max_port != 0 && daemon->min_port == 0)
+    daemon->min_port = MIN_PORT;
+   
   if (daemon->max_port < daemon->min_port)
     die(_("max_port cannot be smaller than min_port"), NULL, EC_BADCONF);
-
+  
   now = dnsmasq_time();
 
   if (daemon->auth_zones)
@@ -390,8 +408,16 @@ int main (int argc, char **argv)
   if (daemon->port != 0)
     {
       cache_init();
-
       blockdata_init();
+      hash_questions_init();
+
+      /* Scale random socket pool by ftabsize, but
+        limit it based on available fds. */
+      daemon->numrrand = daemon->ftabsize/2;
+      if (daemon->numrrand > max_fd/3)
+       daemon->numrrand = max_fd/3;
+      /* safe_malloc returns zero'd memory */
+      daemon->randomsocks = safe_malloc(daemon->numrrand * sizeof(struct randfd));
     }
 
 #ifdef HAVE_INOTIFY
@@ -415,8 +441,6 @@ int main (int argc, char **argv)
 #ifdef HAVE_DBUS
     {
       char *err;
-      daemon->dbus = NULL;
-      daemon->watches = NULL;
       if ((err = dbus_init()))
        die(_("DBus error: %s"), err, EC_MISC);
     }
@@ -427,8 +451,9 @@ int main (int argc, char **argv)
   if (option_bool(OPT_UBUS))
 #ifdef HAVE_UBUS
     {
-      daemon->ubus = NULL;
-      ubus_init();
+      char *err;
+      if ((err = ubus_init()))
+       die(_("UBus error: %s"), err, EC_MISC);
     }
 #else
   die(_("UBus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
@@ -980,7 +1005,7 @@ int main (int argc, char **argv)
         a single file will be sent to may clients (the file only needs
         one fd). */
 
-      max_fd -= 30; /* use other than TFTP */
+      max_fd -= 30 + daemon->numrrand; /* use other than TFTP */
       
       if (max_fd < 0)
        max_fd = 5;
@@ -1010,7 +1035,7 @@ int main (int argc, char **argv)
     close(err_pipe[1]);
   
   if (daemon->port != 0)
-    check_servers();
+    check_servers(0);
   
   pid = getpid();
 
@@ -1025,16 +1050,10 @@ int main (int argc, char **argv)
   
   while (1)
     {
-      int t, timeout = -1;
+      int timeout = -1;
       
       poll_reset();
       
-      /* if we are out of resources, find how long we have to wait
-        for some to come free, we'll loop around then and restart
-        listening for queries */
-      if ((t = set_dns_listeners(now)) != 0)
-       timeout = t * 1000;
-
       /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
       if (daemon->tftp_trans ||
          (option_bool(OPT_DBUS) && !daemon->dbus))
@@ -1044,15 +1063,18 @@ int main (int argc, char **argv)
       else if (is_dad_listeners())
        timeout = 1000;
 
+      set_dns_listeners();
+
 #ifdef HAVE_DBUS
-      set_dbus_listeners();
+      if (option_bool(OPT_DBUS))
+       set_dbus_listeners();
 #endif
-
+      
 #ifdef HAVE_UBUS
       if (option_bool(OPT_UBUS))
         set_ubus_listeners();
 #endif
-         
+      
 #ifdef HAVE_DHCP
       if (daemon->dhcp || daemon->relay4)
        {
@@ -1172,28 +1194,44 @@ int main (int argc, char **argv)
       
 #ifdef HAVE_DBUS
       /* if we didn't create a DBus connection, retry now. */ 
-     if (option_bool(OPT_DBUS) && !daemon->dbus)
+      if (option_bool(OPT_DBUS))
        {
-         char *err;
-         if ((err = dbus_init()))
-           my_syslog(LOG_WARNING, _("DBus error: %s"), err);
-         if (daemon->dbus)
-           my_syslog(LOG_INFO, _("connected to system DBus"));
+         if (!daemon->dbus)
+           {
+             char *err  = dbus_init();
+
+             if (daemon->dbus)
+               my_syslog(LOG_INFO, _("connected to system DBus"));
+             else if (err)
+               {
+                 my_syslog(LOG_ERR, _("DBus error: %s"), err);
+                 reset_option_bool(OPT_DBUS); /* fatal error, stop trying. */
+               }
+           }
+         
+         check_dbus_listeners();
        }
-      check_dbus_listeners();
 #endif
 
 #ifdef HAVE_UBUS
+      /* if we didn't create a UBus connection, retry now. */
       if (option_bool(OPT_UBUS))
-        {
-          /* if we didn't create a UBus connection, retry now. */
-          if (!daemon->ubus)
-            {
-              ubus_init();
-            }
+       {
+         if (!daemon->ubus)
+           {
+             char *err = ubus_init();
 
-          check_ubus_listeners();
-        }
+             if (daemon->ubus)
+               my_syslog(LOG_INFO, _("connected to system UBus"));
+             else if (err)
+               {
+                 my_syslog(LOG_ERR, _("UBus error: %s"), err);
+                 reset_option_bool(OPT_UBUS); /* fatal error, stop trying. */
+               }
+           }
+         
+         check_ubus_listeners();
+       }
 #endif
 
       check_dns_listeners(now);
@@ -1426,7 +1464,7 @@ static void async_event(int pipe, time_t now)
              }
 
            if (check)
-             check_servers();
+             check_servers(0);
          }
 
 #ifdef HAVE_DHCP
@@ -1625,7 +1663,7 @@ static void poll_resolv(int force, int do_reload, time_t now)
        {
          my_syslog(LOG_INFO, _("reading %s"), latest->name);
          warned = 0;
-         check_servers();
+         check_servers(0);
          if (option_bool(OPT_RELOAD) && do_reload)
            clear_cache_and_reload(now);
        }
@@ -1668,11 +1706,12 @@ void clear_cache_and_reload(time_t now)
 #endif
 }
 
-static int set_dns_listeners(time_t now)
+static void set_dns_listeners(void)
 {
   struct serverfd *serverfdp;
   struct listener *listener;
-  int wait = 0, i;
+  struct randfd_list *rfl;
+  int i;
   
 #ifdef HAVE_TFTP
   int  tftp = 0;
@@ -1685,66 +1724,68 @@ static int set_dns_listeners(time_t now)
       }
 #endif
   
-  /* will we be able to get memory? */
-  if (daemon->port != 0)
-    get_new_frec(now, &wait, NULL);
-  
   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
     poll_listen(serverfdp->fd, POLLIN);
     
-  if (daemon->port != 0 && !daemon->osport)
-    for (i = 0; i < RANDOM_SOCKS; i++)
-      if (daemon->randomsocks[i].refcount != 0)
-       poll_listen(daemon->randomsocks[i].fd, POLLIN);
-         
+  for (i = 0; i < daemon->numrrand; i++)
+    if (daemon->randomsocks[i].refcount != 0)
+      poll_listen(daemon->randomsocks[i].fd, POLLIN);
+
+  /* Check overflow random sockets too. */
+  for (rfl = daemon->rfl_poll; rfl; rfl = rfl->next)
+    poll_listen(rfl->rfd->fd, POLLIN);
+  
+  /* check to see if we have free tcp process slots. */
+  for (i = MAX_PROCS - 1; i >= 0; i--)
+    if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
+      break;
+
   for (listener = daemon->listeners; listener; listener = listener->next)
     {
-      /* only listen for queries if we have resources */
-      if (listener->fd != -1 && wait == 0)
+      if (listener->fd != -1)
        poll_listen(listener->fd, POLLIN);
-       
-      /* death of a child goes through the select loop, so
-        we don't need to explicitly arrange to wake up here */
-      if  (listener->tcpfd != -1)
-       for (i = 0; i < MAX_PROCS; i++)
-         if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
-           {
-             poll_listen(listener->tcpfd, POLLIN);
-             break;
-           }
-
+      
+      /* Only listen for TCP connections when a process slot
+        is available. Death of a child goes through the select loop, so
+        we don't need to explicitly arrange to wake up here,
+        we'll be called again when a slot becomes available. */
+      if  (listener->tcpfd != -1 && i >= 0)
+       poll_listen(listener->tcpfd, POLLIN);
+      
 #ifdef HAVE_TFTP
       /* tftp == 0 in single-port mode. */
       if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
        poll_listen(listener->tftpfd, POLLIN);
 #endif
-
     }
   
   if (!option_bool(OPT_DEBUG))
     for (i = 0; i < MAX_PROCS; i++)
       if (daemon->tcp_pipes[i] != -1)
        poll_listen(daemon->tcp_pipes[i], POLLIN);
-  
-  return wait;
 }
 
 static void check_dns_listeners(time_t now)
 {
   struct serverfd *serverfdp;
   struct listener *listener;
+  struct randfd_list *rfl;
   int i;
   int pipefd[2];
   
   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
     if (poll_check(serverfdp->fd, POLLIN))
-      reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
+      reply_query(serverfdp->fd, now);
   
-  if (daemon->port != 0 && !daemon->osport)
-    for (i = 0; i < RANDOM_SOCKS; i++)
-      if (daemon->randomsocks[i].refcount != 0 && 
-         poll_check(daemon->randomsocks[i].fd, POLLIN))
-       reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
+  for (i = 0; i < daemon->numrrand; i++)
+    if (daemon->randomsocks[i].refcount != 0 && 
+       poll_check(daemon->randomsocks[i].fd, POLLIN))
+      reply_query(daemon->randomsocks[i].fd, now);
+
+  /* Check overflow random sockets too. */
+  for (rfl = daemon->rfl_poll; rfl; rfl = rfl->next)
+    if (poll_check(rfl->rfd->fd, POLLIN))
+      reply_query(rfl->rfd->fd, now);
 
   /* Races. The child process can die before we read all of the data from the
      pipe, or vice versa. Therefore send tcp_pids to zero when we wait() the 
@@ -1773,7 +1814,16 @@ static void check_dns_listeners(time_t now)
        tftp_request(listener, now);
 #endif
 
-      if (listener->tcpfd != -1 && poll_check(listener->tcpfd, POLLIN))
+      /* check to see if we have a free tcp process slot.
+        Note that we can't assume that because we had
+        at least one a poll() time, that we still do.
+        There may be more waiting connections after
+        poll() returns then free process slots. */
+      for (i = MAX_PROCS - 1; i >= 0; i--)
+       if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
+         break;
+
+      if (listener->tcpfd != -1 && i >= 0 && poll_check(listener->tcpfd, POLLIN))
        {
          int confd, client_ok = 1;
          struct irec *iface = NULL;
@@ -1863,7 +1913,6 @@ static void check_dns_listeners(time_t now)
                close(pipefd[0]);
              else
                {
-                 int i;
 #ifdef HAVE_LINUX_NETWORK
                  /* The child process inherits the netlink socket, 
                     which it never uses, but when the parent (us) 
@@ -1883,13 +1932,9 @@ static void check_dns_listeners(time_t now)
                  read_write(pipefd[0], &a, 1, 1);
 #endif
 
-                 for (i = 0; i < MAX_PROCS; i++)
-                   if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
-                     {
-                       daemon->tcp_pids[i] = p;
-                       daemon->tcp_pipes[i] = pipefd[0];
-                       break;
-                     }
+                 /* i holds index of free slot */
+                 daemon->tcp_pids[i] = p;
+                 daemon->tcp_pipes[i] = pipefd[0];
                }
              close(confd);
 
@@ -2068,7 +2113,7 @@ int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id)
       poll_reset();
       if (fd != -1)
         poll_listen(fd, POLLIN);
-      set_dns_listeners(now);
+      set_dns_listeners();
       set_log_writer();
       
 #ifdef HAVE_DHCP6
index 914f469..8674823 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
  
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#define COPYRIGHT "Copyright (c) 2000-2020 Simon Kelley"
+#define COPYRIGHT "Copyright (c) 2000-2021 Simon Kelley"
 
 /* We do defines that influence behavior of stdio.h, so complain
    if included too early. */
@@ -95,11 +95,7 @@ typedef unsigned long long u64;
 #if defined(HAVE_SOLARIS_NETWORK)
 #  include <sys/sockio.h>
 #endif
-#if defined(HAVE_POLL_H)
-#  include <poll.h>
-#else
-#  include <sys/poll.h>
-#endif
+#include <poll.h>
 #include <sys/wait.h>
 #include <sys/time.h>
 #include <sys/un.h>
@@ -111,6 +107,7 @@ typedef unsigned long long u64;
 #endif
 #include <unistd.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <string.h>
 #include <stdlib.h>
 #include <fcntl.h>
@@ -157,7 +154,11 @@ extern int capget(cap_user_header_t header, cap_user_data_t data);
 #include <priv.h>
 #endif
 
-#if defined(HAVE_DNSSEC) || defined(HAVE_NETTLEHASH)
+/* Backwards compat with 2.83 */
+#if defined(HAVE_NETTLEHASH)
+#  define HAVE_CRYPTOHASH
+#endif
+#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH)
 #  include <nettle/nettle-meta.h>
 #endif
 
@@ -269,7 +270,12 @@ struct event_desc {
 #define OPT_IGNORE_CLID    59
 #define OPT_SINGLE_PORT    60
 #define OPT_LEASE_RENEW    61
-#define OPT_LAST           62
+#define OPT_LOG_DEBUG      62
+#define OPT_UMBRELLA       63
+#define OPT_UMBRELLA_DEVID 64
+#define OPT_CMARK_ALST_EN  65
+#define OPT_QUIET_TFTP     66
+#define OPT_LAST           67
 
 #define OPTION_BITS (sizeof(unsigned int)*8)
 #define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
@@ -277,11 +283,13 @@ struct event_desc {
 #define option_val(x) ((1u) << ((x) % OPTION_BITS))
 #define option_bool(x) (option_var(x) & option_val(x))
 
-/* extra flags for my_syslog, we use a couple of facilities since they are known 
-   not to occupy the same bits as priorities, no matter how syslog.h is set up. */
+/* extra flags for my_syslog, we use facilities since they are known 
+   not to occupy the same bits as priorities, no matter how syslog.h is set up. 
+   MS_DEBUG messages are suppressed unless --log-debug is set. */
 #define MS_TFTP   LOG_USER
 #define MS_DHCP   LOG_DAEMON
 #define MS_SCRIPT LOG_MAIL
+#define MS_DEBUG  LOG_NEWS
 
 /* Note that this is used widely as a container for IPv4/IPv6 addresses,
    so for that reason, was well as to avoid wasting memory in almost every
@@ -317,12 +325,14 @@ union all_addr {
   /* for log_query */
   struct {
     unsigned short keytag, algo, digest, rcode;
+    int ede;
   } log;
 };
 
 
 struct bogus_addr {
-  struct in_addr addr;
+  int is6, prefix;
+  union all_addr addr;
   struct bogus_addr *next;
 };
 
@@ -423,10 +433,17 @@ struct host_record {
   struct host_record *next;
 };
 
+#define IN4  1
+#define IN6  2
+#define INP4 4
+#define INP6 8
+
 struct interface_name {
   char *name; /* domain name */
   char *intr; /* interface name */
-  int family; /* AF_INET, AF_INET6 or zero for both */
+  int flags;
+  struct in_addr proto4;
+  struct in6_addr proto6;
   struct addrlist *addr;
   struct interface_name *next;
 };
@@ -486,7 +503,7 @@ struct crec {
 #define F_NO_RR     (1u<<25)
 #define F_IPSET     (1u<<26)
 #define F_NOEXTRA   (1u<<27)
-#define F_SERVFAIL  (1u<<28) /* currently unused. */
+#define F_DOMAINSRV (1u<<28)
 #define F_RCODE     (1u<<29)
 #define F_SRV       (1u<<30)
 
@@ -512,19 +529,20 @@ union mysockaddr {
 #define IFACE_PERMANENT   4
 
 
-#define SERV_FROM_RESOLV       1  /* 1 for servers from resolv, 0 for command line. */
-#define SERV_NO_ADDR           2  /* no server, this domain is local only */
-#define SERV_LITERAL_ADDRESS   4  /* addr is the answer, not the server */ 
-#define SERV_HAS_DOMAIN        8  /* server for one domain only */
+/* The actual values here matter, since we sort on them to get records in the order
+   IPv6 addr, IPv4 addr, all zero return, no-data return, send upstream. */
+#define SERV_LITERAL_ADDRESS   1  /* addr is the answer, or NoDATA is the answer, depending on the next three flags */
+#define SERV_ALL_ZEROS         2  /* return all zeros for A and AAAA */
+#define SERV_4ADDR             4  /* addr is IPv4 */
+#define SERV_6ADDR             8  /* addr is IPv6 */
 #define SERV_HAS_SOURCE       16  /* source address defined */
 #define SERV_FOR_NODOTS       32  /* server for names with no domain part only */
 #define SERV_WARNED_RECURSIVE 64  /* avoid warning spam */
 #define SERV_FROM_DBUS       128  /* 1 if source is DBus */
-#define SERV_MARK            256  /* for mark-and-delete */
-#define SERV_TYPE    (SERV_HAS_DOMAIN | SERV_FOR_NODOTS)
-#define SERV_COUNTED         512  /* workspace for log code */
+#define SERV_MARK            256  /* for mark-and-delete and log code */
+#define SERV_WILDCARD        512  /* domain has leading '*' */ 
 #define SERV_USE_RESOLV     1024  /* forward this domain in the normal way */
-#define SERV_NO_REBIND      2048  /* inhibit dns-rebind protection */
+#define SERV_FROM_RESOLV    2048  /* 1 for servers from resolv, 0 for command line. */
 #define SERV_FROM_FILE      4096  /* read from --servers-file */
 #define SERV_LOOP           8192  /* server causes forwarding loop */
 #define SERV_DO_DNSSEC     16384  /* Validate DNSSEC when using this server */
@@ -539,22 +557,56 @@ struct serverfd {
 };
 
 struct randfd {
+  struct server *serv;
   int fd;
-  unsigned short refcount, family;
+  unsigned short refcount; /* refcount == 0xffff means overflow record. */
 };
-  
+
+struct randfd_list {
+  struct randfd *rfd;
+  struct randfd_list *next;
+};
+
+
 struct server {
+  u16 flags, domain_len;
+  char *domain;
+  struct server *next;
+  int serial, arrayposn;
+  int last_server;
   union mysockaddr addr, source_addr;
   char interface[IF_NAMESIZE+1];
+  unsigned int ifindex; /* corresponding to interface, above */
   struct serverfd *sfd; 
-  char *domain; /* set if this server only handles a domain. */ 
-  int flags, tcpfd, edns_pktsz;
+  int tcpfd, edns_pktsz;
   time_t pktsz_reduced;
   unsigned int queries, failed_queries;
+  time_t forwardtime;
+  int forwardcount;
 #ifdef HAVE_LOOP
   u32 uid;
 #endif
-  struct server *next; 
+};
+
+/* First four fields must match struct server in next three definitions.. */
+struct serv_addr4 {
+  u16 flags, domain_len;
+  char *domain;
+  struct server *next;
+  struct in_addr addr;
+};
+
+struct serv_addr6 {
+  u16 flags, domain_len;
+  char *domain;
+  struct server *next;
+  struct in6_addr addr;
+};
+
+struct serv_local {
+  u16 flags, domain_len;
+  char *domain;
+  struct server *next;
 };
 
 struct ipsets {
@@ -563,6 +615,12 @@ struct ipsets {
   struct ipsets *next;
 };
 
+struct allowlist {
+  u32 mark, mask;
+  char **patterns;
+  struct allowlist *next;
+};
+
 struct irec {
   union mysockaddr addr;
   struct in_addr netmask; /* only valid for IPv4 */
@@ -632,17 +690,28 @@ struct hostsfile {
 #define DUMP_BOGUS     0x0040
 #define DUMP_SEC_BOGUS 0x0080
 
-
 /* DNSSEC status values. */
-#define STAT_SECURE             1
-#define STAT_INSECURE           2
-#define STAT_BOGUS              3
-#define STAT_NEED_DS            4
-#define STAT_NEED_KEY           5
-#define STAT_TRUNCATED          6
-#define STAT_SECURE_WILDCARD    7
-#define STAT_OK                 8
-#define STAT_ABANDONED          9
+#define STAT_SECURE             0x10000
+#define STAT_INSECURE           0x20000
+#define STAT_BOGUS              0x30000
+#define STAT_NEED_DS            0x40000
+#define STAT_NEED_KEY           0x50000
+#define STAT_TRUNCATED          0x60000
+#define STAT_SECURE_WILDCARD    0x70000
+#define STAT_OK                 0x80000
+#define STAT_ABANDONED          0x90000
+
+#define DNSSEC_FAIL_NYV         0x0001 /* key not yet valid */
+#define DNSSEC_FAIL_EXP         0x0002 /* key expired */
+#define DNSSEC_FAIL_INDET       0x0004 /* indetermined */
+#define DNSSEC_FAIL_NOKEYSUP    0x0008 /* no supported key algo. */
+#define DNSSEC_FAIL_NOSIG       0x0010 /* No RRsigs */
+#define DNSSEC_FAIL_NOZONE      0x0020 /* No Zone bit set */
+#define DNSSEC_FAIL_NONSEC      0x0040 /* No NSEC */
+#define DNSSEC_FAIL_NODSSUP     0x0080 /* no supported DS algo. */
+#define DNSSEC_FAIL_NOKEY       0x0100 /* no DNSKEY */
+
+#define STAT_ISEQUAL(a, b)  (((a) & 0xffff0000) == (b))
 
 #define FREC_NOREBIND           1
 #define FREC_CHECKING_DISABLED  2
@@ -664,14 +733,14 @@ struct frec {
     union mysockaddr source;
     union all_addr dest;
     unsigned int iface, log_id;
+    int fd;
     unsigned short orig_id;
     struct frec_src *next;
   } frec_src;
   struct server *sentto; /* NULL means free */
-  struct randfd *rfd4;
-  struct randfd *rfd6;
+  struct randfd_list *rfds;
   unsigned short new_id;
-  int fd, forwardall, flags;
+  int forwardall, flags;
   time_t time;
   unsigned char *hash[HASH_SIZE];
 #ifdef HAVE_DNSSEC 
@@ -679,6 +748,7 @@ struct frec {
   struct blockdata *stash; /* Saved reply, whilst we validate */
   size_t stash_len;
   struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */
+  struct frec *next_dependent; /* list of above. */
   struct frec *blocking_query; /* Query which is blocking us. */
 #endif
   struct frec *next;
@@ -891,10 +961,10 @@ struct dhcp_bridge {
 };
 
 struct cond_domain {
-  char *domain, *prefix;
+  char *domain, *prefix; /* prefix is text-prefix on domain name */
   struct in_addr start, end;
   struct in6_addr start6, end6;
-  int is6, indexed;
+  int is6, indexed, prefixlen;
   struct cond_domain *next;
 }; 
 
@@ -1035,8 +1105,12 @@ extern struct daemon {
   char *lease_change_command;
   struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
   struct bogus_addr *bogus_addr, *ignore_addr;
-  struct server *servers;
+  struct server *servers, *local_domains, **serverarray, *no_rebind;
+  int server_has_wildcard;
+  int serverarraysz, serverarrayhwm;
   struct ipsets *ipsets;
+  u32 allowlist_mask;
+  struct allowlist *allowlists;
   int log_fac; /* log facility */
   char *log_file; /* optional log file */
   int max_logs;  /* queue limit */
@@ -1044,6 +1118,9 @@ extern struct daemon {
   int port, query_port, min_port, max_port;
   unsigned long local_ttl, neg_ttl, max_ttl, min_cache_ttl, max_cache_ttl, auth_ttl, dhcp_ttl, use_dhcp_ttl;
   char *dns_client_id;
+  u32 umbrella_org;
+  u32 umbrella_asset;
+  u8 umbrella_device[8];
   struct hostsfile *addn_hosts;
   struct dhcp_context *dhcp, *dhcp6;
   struct ra_interface *ra_interfaces;
@@ -1104,16 +1181,15 @@ extern struct daemon {
   struct serverfd *sfds;
   struct irec *interfaces;
   struct listener *listeners;
-  struct server *last_server;
-  time_t forwardtime;
-  int forwardcount;
   struct server *srv_save; /* Used for resend on DoD */
   size_t packet_len;       /*      "        "        */
-  struct randfd *rfd_save; /*      "        "        */
+  int    fd_save;          /*      "        "        */
   pid_t tcp_pids[MAX_PROCS];
   int tcp_pipes[MAX_PROCS];
   int pipe_to_parent;
-  struct randfd randomsocks[RANDOM_SOCKS];
+  int numrrand;
+  struct randfd *randomsocks;
+  struct randfd_list *rfl_spare, *rfl_poll;
   int v6pktinfo; 
   struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */
   int log_id, log_display_id; /* ids of transactions for logging */
@@ -1220,18 +1296,19 @@ unsigned char *skip_questions(struct dns_header *header, size_t plen);
 unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen);
 unsigned int extract_request(struct dns_header *header, size_t qlen, 
                               char *name, unsigned short *typep);
-size_t setup_reply(struct dns_header *header, size_t  qlen,
-                  union all_addr *addrp, unsigned int flags,
-                  unsigned long ttl);
+void setup_reply(struct dns_header *header, unsigned int flags, int ede);
 int extract_addresses(struct dns_header *header, size_t qlen, char *name,
                      time_t now, char **ipsets, int is_sign, int check_rebind,
                      int no_cache_dnssec, int secure, int *doctored);
+#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
+void report_addresses(struct dns_header *header, size_t len, u32 mark);
+#endif
 size_t answer_request(struct dns_header *header, char *limit, size_t qlen,  
                      struct in_addr local_addr, struct in_addr local_netmask, 
                      time_t now, int ad_reqd, int do_bit, int have_pseudoheader);
 int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, 
-                            struct bogus_addr *baddr, time_t now);
-int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr);
+                            time_t now);
+int check_for_ignored_address(struct dns_header *header, size_t qlen);
 int check_for_local_domain(char *name, time_t now);
 size_t resize_packet(struct dns_header *header, size_t plen, 
                  unsigned char *pheader, size_t hlen);
@@ -1250,6 +1327,7 @@ int in_zone(struct auth_zone *zone, char *name, char **cut);
 #endif
 
 /* dnssec.c */
+#ifdef HAVE_DNSSEC
 size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int type, int edns_pktsz);
 int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
 int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
@@ -1258,8 +1336,11 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
 int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen);
 size_t filter_rrsigs(struct dns_header *header, size_t plen);
 int setup_timestamp(void);
+int errflags_to_ede(int status);
+#endif
 
 /* hash_questions.c */
+void hash_questions_init(void);
 unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name);
 
 /* crypto.c */
@@ -1284,12 +1365,13 @@ void safe_strncpy(char *dest, const char *src, size_t size);
 void safe_pipe(int *fd, int read_noblock);
 void *whine_malloc(size_t size);
 int sa_len(union mysockaddr *addr);
-int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
+int sockaddr_isequal(const union mysockaddr *s1, const union mysockaddr *s2);
 int hostname_isequal(const char *a, const char *b);
 int hostname_issubdomain(char *a, char *b);
 time_t dnsmasq_time(void);
 int netmask_length(struct in_addr mask);
 int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
+int is_same_net_prefix(struct in_addr a, struct in_addr b, int prefix);
 int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen);
 u64 addr6part(struct in6_addr *addr);
 void setaddr6part(struct in6_addr *addr, u64 host);
@@ -1331,37 +1413,28 @@ void set_option_bool(unsigned int opt);
 void reset_option_bool(unsigned int opt);
 struct hostsfile *expand_filelist(struct hostsfile *list);
 char *parse_server(char *arg, union mysockaddr *addr, 
-                  union mysockaddr *source_addr, char *interface, int *flags);
+                  union mysockaddr *source_addr, char *interface, u16 *flags);
 int option_read_dynfile(char *file, int flags);
 
 /* forward.c */
-void reply_query(int fd, int family, time_t now);
+void reply_query(int fd, time_t now);
 void receive_query(struct listener *listen, time_t now);
 unsigned char *tcp_request(int confd, time_t now,
                           union mysockaddr *local_addr, struct in_addr netmask, int auth_dns);
 void server_gone(struct server *server);
-struct frec *get_new_frec(time_t now, int *wait, struct frec *force);
 int send_from(int fd, int nowild, char *packet, size_t len, 
               union mysockaddr *to, union all_addr *source,
               unsigned int iface);
 void resend_query(void);
-struct randfd *allocate_rfd(int family);
-void free_rfd(struct randfd *rfd);
+int allocate_rfd(struct randfd_list **fdlp, struct server *serv);
+void free_rfds(struct randfd_list **fdlp);
 
 /* network.c */
 int indextoname(int fd, int index, char *name);
 int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp);
-int random_sock(int family);
 void pre_allocate_sfds(void);
 int reload_servers(char *fname);
-void mark_servers(int flag);
-void cleanup_servers(void);
-void add_update_server(int flags,
-                      union mysockaddr *addr,
-                      union mysockaddr *source_addr,
-                      const char *interface,
-                      const char *domain);
-void check_servers(void);
+void check_servers(int no_loop_call);
 int enumerate_interfaces(int reset);
 void create_wildcard_listeners(void);
 void create_bound_listeners(int dienow);
@@ -1494,10 +1567,14 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname);
 
 /* ubus.c */
 #ifdef HAVE_UBUS
-void ubus_init(void);
+char *ubus_init(void);
 void set_ubus_listeners(void);
 void check_ubus_listeners(void);
 void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface);
+#  ifdef HAVE_CONNTRACK
+void ubus_event_bcast_connmark_allowlist_refused(u32 mark, const char *name);
+void ubus_event_bcast_connmark_allowlist_resolved(u32 mark, const char *pattern, const char *ip, u32 ttl);
+#  endif
 #endif
 
 /* ipset.c */
@@ -1506,6 +1583,13 @@ void ipset_init(void);
 int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove);
 #endif
 
+/* pattern.c */
+#ifdef HAVE_CONNTRACK
+int is_valid_dns_name(const char *value);
+int is_valid_dns_name_pattern(const char *value);
+int is_dns_name_matching_pattern(const char *name, const char *pattern);
+#endif
+
 /* helper.c */
 #if defined(HAVE_SCRIPT)
 int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd);
@@ -1671,3 +1755,23 @@ int do_arp_script_run(void);
 void dump_init(void);
 void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, union mysockaddr *dst);
 #endif
+
+/* domain-match.c */
+void build_server_array(void);
+int lookup_domain(char *qdomain, int flags, int *lowout, int *highout);
+int filter_servers(int seed, int flags, int *lowout, int *highout);
+int is_local_answer(time_t now, int first, char *name);
+size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header *header,
+                        char *name, char *limit, int first, int last, int ede);
+int server_samegroup(struct server *a, struct server *b);
+#ifdef HAVE_DNSSEC
+int dnssec_server(struct server *server, char *keyname, int *firstp, int *lastp);
+#endif
+void mark_servers(int flag);
+void cleanup_servers(void);
+int add_update_server(int flags,
+                     union mysockaddr *addr,
+                     union mysockaddr *source_addr,
+                     const char *interface,
+                     const char *domain,
+                     union all_addr *local_addr); 
index 93cc7bf..153cac4 100644 (file)
@@ -215,14 +215,6 @@ static int is_check_date(unsigned long curtime)
     return !daemon->dnssec_no_time_check;
 }
 
-/* Check whether today/now is between date_start and date_end */
-static int check_date_range(unsigned long curtime, u32 date_start, u32 date_end)
-{
-  /* We must explicitly check against wanted values, because of SERIAL_UNDEF */
-  return serial_compare_32(curtime, date_start) == SERIAL_GT
-    && serial_compare_32(curtime, date_end) == SERIAL_LT;
-}
-
 /* Return bytes of canonicalised rrdata one by one.
    Init state->ip with the RR, and state->end with the end of same.
    Init state->op to NULL.
@@ -334,37 +326,64 @@ static int sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
          if (!CHECK_LEN(header, state2.ip, plen, rdlen2))
            return rrsetidx; /* short packet */
          state2.end = state2.ip + rdlen2; 
-                 
-         while (1)
+
+         /* If the RR has no names in it then canonicalisation
+            is the identity function and we can compare
+            the RRs directly. If not we compare the 
+            canonicalised RRs one byte at a time. */
+         if (*rr_desc == (u16)-1)        
            {
-             int ok1, ok2;
+             int rdmin = rdlen1 > rdlen2 ? rdlen2 : rdlen1;
+             int cmp = memcmp(state1.ip, state2.ip, rdmin);
              
-             ok1 = get_rdata(header, plen, &state1);
-             ok2 = get_rdata(header, plen, &state2);
-
-             if (!ok1 && !ok2)
+             if (cmp > 0 || (cmp == 0 && rdlen1 > rdmin))
+               {
+                 unsigned char *tmp = rrset[i+1];
+                 rrset[i+1] = rrset[i];
+                 rrset[i] = tmp;
+                 swap = 1;
+               }
+             else if (cmp == 0 && (rdlen1 == rdlen2))
                {
                  /* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */
                  for (j = i+1; j < rrsetidx-1; j++)
                    rrset[j] = rrset[j+1];
                  rrsetidx--;
                  i--;
-                 break;
                }
-             else if (ok1 && (!ok2 || *state1.op > *state2.op)) 
-               {
-                 unsigned char *tmp = rrset[i+1];
-                 rrset[i+1] = rrset[i];
-                 rrset[i] = tmp;
-                 swap = 1;
-                 break;
-               }
-             else if (ok2 && (!ok1 || *state2.op > *state1.op))
-               break;
-             
-             /* arrive here when bytes are equal, go round the loop again
-                and compare the next ones. */
            }
+         else
+           /* Comparing canonicalised RRs, byte-at-a-time. */
+           while (1)
+             {
+               int ok1, ok2;
+               
+               ok1 = get_rdata(header, plen, &state1);
+               ok2 = get_rdata(header, plen, &state2);
+               
+               if (!ok1 && !ok2)
+                 {
+                   /* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */
+                   for (j = i+1; j < rrsetidx-1; j++)
+                     rrset[j] = rrset[j+1];
+                   rrsetidx--;
+                   i--;
+                   break;
+                 }
+               else if (ok1 && (!ok2 || *state1.op > *state2.op)) 
+                 {
+                   unsigned char *tmp = rrset[i+1];
+                   rrset[i+1] = rrset[i];
+                   rrset[i] = tmp;
+                   swap = 1;
+                   break;
+                 }
+               else if (ok2 && (!ok1 || *state2.op > *state1.op))
+                 break;
+               
+               /* arrive here when bytes are equal, go round the loop again
+                  and compare the next ones. */
+             }
        }
     } while (swap);
 
@@ -507,7 +526,8 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
   struct crec *crecp = NULL;
   u16 *rr_desc = rrfilter_desc(type);
   u32 sig_expiration, sig_inception;
-
+  int failflags = DNSSEC_FAIL_NOSIG | DNSSEC_FAIL_NYV | DNSSEC_FAIL_EXP | DNSSEC_FAIL_NOKEYSUP;
+  
   unsigned long curtime = time(0);
   int time_check = is_check_date(curtime);
   
@@ -530,6 +550,8 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
       void *ctx;
       char *name_start;
       u32 nsigttl, ttl, orig_ttl;
+
+      failflags &= ~DNSSEC_FAIL_NOSIG;
       
       p = sigs[j];
       GETLONG(ttl, p);
@@ -547,12 +569,31 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
       if (!extract_name(header, plen, &p, keyname, 1, 0))
        return STAT_BOGUS;
 
-      if ((time_check && !check_date_range(curtime, sig_inception, sig_expiration)) ||
-         labels > name_labels ||
-         !(hash = hash_find(algo_digest_name(algo))) ||
+      if (!time_check)
+       failflags &= ~(DNSSEC_FAIL_NYV | DNSSEC_FAIL_EXP);
+      else
+       {
+         /* We must explicitly check against wanted values, because of SERIAL_UNDEF */
+         if (serial_compare_32(curtime, sig_inception) == SERIAL_LT)
+           continue;
+         else
+           failflags &= ~DNSSEC_FAIL_NYV;
+         
+         if (serial_compare_32(curtime, sig_expiration) == SERIAL_GT)
+           continue;
+         else
+           failflags &= ~DNSSEC_FAIL_EXP;
+       }
+
+      if (!(hash = hash_find(algo_digest_name(algo))))
+       continue;
+      else
+       failflags &= ~DNSSEC_FAIL_NOKEYSUP;
+      
+      if (labels > name_labels ||
          !hash_init(hash, &ctx, &digest))
        continue;
-
+      
       /* OK, we have the signature record, see if the relevant DNSKEY is in the cache. */
       if (!key && !(crecp = cache_find_by_name(NULL, keyname, now, F_DNSKEY)))
        return STAT_NEED_KEY;
@@ -703,7 +744,8 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
        }
     }
 
-  return STAT_BOGUS;
+  /* If we reach this point, no verifying key was found */
+  return STAT_BOGUS | failflags | DNSSEC_FAIL_NOKEY;
 }
  
 
@@ -724,17 +766,18 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
   unsigned long ttl, sig_ttl;
   struct blockdata *key;
   union all_addr a;
+  int failflags = DNSSEC_FAIL_NOSIG | DNSSEC_FAIL_NODSSUP | DNSSEC_FAIL_NOZONE | DNSSEC_FAIL_NOKEY;
 
   if (ntohs(header->qdcount) != 1 ||
       RCODE(header) == SERVFAIL || RCODE(header) == REFUSED ||
       !extract_name(header, plen, &p, name, 1, 4))
-    return STAT_BOGUS;
+    return STAT_BOGUS | DNSSEC_FAIL_NOKEY;
 
   GETSHORT(qtype, p);
   GETSHORT(qclass, p);
   
   if (qtype != T_DNSKEY || qclass != class || ntohs(header->ancount) == 0)
-    return STAT_BOGUS;
+    return STAT_BOGUS | DNSSEC_FAIL_NOKEY;
 
   /* See if we have cached a DS record which validates this key */
   if (!(crecp = cache_find_by_name(NULL, name, now, F_DS)))
@@ -768,14 +811,17 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
       
       GETSHORT(flags, p);
       if (*p++ != 3)
-       return STAT_BOGUS;
+       return STAT_BOGUS | DNSSEC_FAIL_NOKEY;
       algo = *p++;
       keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
       key = NULL;
       
       /* key must have zone key flag set */
       if (flags & 0x100)
-       key = blockdata_alloc((char*)p, rdlen - 4);
+       {
+         key = blockdata_alloc((char*)p, rdlen - 4);
+         failflags &= ~DNSSEC_FAIL_NOZONE;
+       }
       
       p = psave;
       
@@ -796,15 +842,23 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
          unsigned char *digest, *ds_digest;
          const struct nettle_hash *hash;
          int sigcnt, rrcnt;
-
+         int wire_len;
+         
          if (recp1->addr.ds.algo == algo && 
              recp1->addr.ds.keytag == keytag &&
-             recp1->uid == (unsigned int)class &&
-             (hash = hash_find(ds_digest_name(recp1->addr.ds.digest))) &&
-             hash_init(hash, &ctx, &digest))
-           
+             recp1->uid == (unsigned int)class)
            {
-             int wire_len = to_wire(name);
+             failflags &= ~DNSSEC_FAIL_NOKEY;
+             
+             if (!(hash = hash_find(ds_digest_name(recp1->addr.ds.digest))))
+               continue;
+             else
+               failflags &= ~DNSSEC_FAIL_NODSSUP;
+
+             if (!hash_init(hash, &ctx, &digest))
+               continue;
+             
+             wire_len = to_wire(name);
              
              /* Note that digest may be different between DSs, so 
                 we can't move this outside the loop. */
@@ -819,12 +873,23 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
                  (ds_digest = blockdata_retrieve(recp1->addr.ds.keydata, recp1->addr.ds.keylen, NULL)) &&
                  memcmp(ds_digest, digest, recp1->addr.ds.keylen) == 0 &&
                  explore_rrset(header, plen, class, T_DNSKEY, name, keyname, &sigcnt, &rrcnt) &&
-                 sigcnt != 0 && rrcnt != 0 &&
-                 validate_rrset(now, header, plen, class, T_DNSKEY, sigcnt, rrcnt, name, keyname, 
-                                NULL, key, rdlen - 4, algo, keytag, &sig_ttl) == STAT_SECURE)
+                 rrcnt != 0)
                {
-                 valid = 1;
-                 break;
+                 if (sigcnt == 0)
+                   continue;
+                 else
+                   failflags &= ~DNSSEC_FAIL_NOSIG;
+                 
+                 rc = validate_rrset(now, header, plen, class, T_DNSKEY, sigcnt, rrcnt, name, keyname, 
+                                     NULL, key, rdlen - 4, algo, keytag, &sig_ttl);
+
+                 failflags &= rc;
+                 
+                 if (STAT_ISEQUAL(rc, STAT_SECURE))
+                   {
+                     valid = 1;
+                     break;
+                   }
                }
            }
        }
@@ -909,7 +974,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
     }
 
   log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DNSKEY");
-  return STAT_BOGUS;
+  return STAT_BOGUS | failflags;
 }
 
 /* The DNS packet is expected to contain the answer to a DS query
@@ -944,10 +1009,11 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
   else
     rc = dnssec_validate_reply(now, header, plen, name, keyname, NULL, 0, &neganswer, &nons, &neg_ttl);
   
-  if (rc == STAT_INSECURE)
+  if (STAT_ISEQUAL(rc, STAT_INSECURE))
     {
       my_syslog(LOG_WARNING, _("Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"), name);
-      rc = STAT_BOGUS;
+      log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS - not secure");
+      return STAT_BOGUS | DNSSEC_FAIL_INDET;
     }
   
   p = (unsigned char *)(header+1);
@@ -957,13 +1023,13 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
   /* If the key needed to validate the DS is on the same domain as the DS, we'll
      loop getting nowhere. Stop that now. This can happen of the DS answer comes
      from the DS's zone, and not the parent zone. */
-  if (rc == STAT_BOGUS || (rc == STAT_NEED_KEY && hostname_isequal(name, keyname)))
+  if (STAT_ISEQUAL(rc, STAT_NEED_KEY) && hostname_isequal(name, keyname))
     {
       log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS");
       return STAT_BOGUS;
     }
   
-  if (rc != STAT_SECURE)
+  if (!STAT_ISEQUAL(rc, STAT_SECURE))
     return rc;
    
   if (!neganswer)
@@ -1429,7 +1495,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
       if (!(p = skip_name(nsecs[i], header, plen, 15)))
        return 0; /* bad packet */
       
-      p += 10; /* type, class, TTL, rdlen */
+     p += 10; /* type, class, TTL, rdlen */
       algo = *p++;
       
       if ((hash = hash_find(nsec3_digest_name(algo))))
@@ -1827,7 +1893,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
   
    /* Find all the targets we're looking for answers to.
      The zeroth array element is for the query, subsequent ones
-     for CNAME targets, unless the query is for a CNAME. */
+     for CNAME targets, unless the query is for a CNAME or ANY. */
 
   if (!expand_workspace(&targets, &target_sz, 0))
     return STAT_BOGUS;
@@ -1846,7 +1912,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
   if (qtype == T_RRSIG)
     return STAT_INSECURE;
   
-  if (qtype != T_CNAME)
+  if (qtype != T_CNAME && qtype != T_ANY)
     for (j = ntohs(header->ancount); j != 0; j--) 
       {
        if (!(p1 = skip_name(p1, header, plen, 10)))
@@ -1932,15 +1998,15 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
                  if (check_unsigned && i < ntohs(header->ancount))
                    {
                      rc = zone_status(name, class1, keyname, now);
-                     if (rc == STAT_SECURE)
-                       rc = STAT_BOGUS;
+                     if (STAT_ISEQUAL(rc, STAT_SECURE))
+                       rc = STAT_BOGUS | DNSSEC_FAIL_NOSIG;
                      if (class)
                        *class = class1; /* Class for NEED_DS or NEED_KEY */
                    }
                  else 
                    rc = STAT_INSECURE; 
                  
-                 if (rc != STAT_INSECURE)
+                 if (!STAT_ISEQUAL(rc, STAT_INSECURE))
                    return rc;
                }
            }
@@ -1951,7 +2017,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
              strcpy(daemon->workspacename, keyname);
              rc = zone_status(daemon->workspacename, class1, keyname, now);
              
-             if (rc == STAT_BOGUS || rc == STAT_NEED_KEY || rc == STAT_NEED_DS)
+             if (STAT_ISEQUAL(rc, STAT_BOGUS) || STAT_ISEQUAL(rc, STAT_NEED_KEY) || STAT_ISEQUAL(rc, STAT_NEED_DS))
                {
                  if (class)
                    *class = class1; /* Class for NEED_DS or NEED_KEY */
@@ -1959,13 +2025,13 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
                }
              
              /* Zone is insecure, don't need to validate RRset */
-             if (rc == STAT_SECURE)
+             if (STAT_ISEQUAL(rc, STAT_SECURE))
                {
                  unsigned long sig_ttl;
                  rc = validate_rrset(now, header, plen, class1, type1, sigcnt,
                                      rrcnt, name, keyname, &wildname, NULL, 0, 0, 0, &sig_ttl);
                  
-                 if (rc == STAT_BOGUS || rc == STAT_NEED_KEY || rc == STAT_NEED_DS)
+                 if (STAT_ISEQUAL(rc, STAT_BOGUS) || STAT_ISEQUAL(rc, STAT_NEED_KEY) || STAT_ISEQUAL(rc, STAT_NEED_DS))
                    {
                      if (class)
                        *class = class1; /* Class for DS or DNSKEY */
@@ -1998,21 +2064,21 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
                     Note that we may not yet have validated the NSEC/NSEC3 RRsets. 
                     That's not a problem since if the RRsets later fail
                     we'll return BOGUS then. */
-                 if (rc == STAT_SECURE_WILDCARD &&
+                 if (STAT_ISEQUAL(rc, STAT_SECURE_WILDCARD) &&
                      !prove_non_existence(header, plen, keyname, name, type1, class1, wildname, NULL, NULL))
-                   return STAT_BOGUS;
+                   return STAT_BOGUS | DNSSEC_FAIL_NONSEC;
 
                  rc = STAT_SECURE;
                }
            }
        }
 
-      if (rc == STAT_INSECURE)
+      if (STAT_ISEQUAL(rc, STAT_INSECURE))
        secure = STAT_INSECURE;
     }
 
   /* OK, all the RRsets validate, now see if we have a missing answer or CNAME target. */
-  if (secure == STAT_SECURE)
+  if (STAT_ISEQUAL(secure, STAT_SECURE))
     for (j = 0; j <targetidx; j++)
       if ((p2 = targets[j]))
        {
@@ -2030,16 +2096,16 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
            {
              /* Empty DS without NSECS */
              if (qtype == T_DS)
-               return STAT_BOGUS;
+               return STAT_BOGUS | DNSSEC_FAIL_NONSEC;
              
-             if ((rc = zone_status(name, qclass, keyname, now)) != STAT_SECURE)
+             if (STAT_ISEQUAL((rc = zone_status(name, qclass, keyname, now)), STAT_SECURE))
                {
                  if (class)
                    *class = qclass; /* Class for NEED_DS or NEED_KEY */
                  return rc;
                } 
              
-             return STAT_BOGUS; /* signed zone, no NSECs */
+             return STAT_BOGUS | DNSSEC_FAIL_NONSEC; /* signed zone, no NSECs */
            }
        }
   
@@ -2103,4 +2169,31 @@ size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char
   return ret;
 }
 
+int errflags_to_ede(int status)
+{
+  /* We can end up with more than one flag set for some errors,
+     so this encodes a rough priority so the (eg) No sig is reported
+     before no-unexpired-sig. */
+
+  if (status & DNSSEC_FAIL_NYV)
+    return EDE_SIG_NYV;
+  else if (status & DNSSEC_FAIL_EXP)
+    return EDE_SIG_EXP;
+  else if (status & DNSSEC_FAIL_NOKEYSUP)
+    return EDE_USUPDNSKEY;
+  else if (status & DNSSEC_FAIL_NOZONE)
+    return EDE_NO_ZONEKEY;
+  else if (status & DNSSEC_FAIL_NOKEY)
+    return EDE_NO_DNSKEY;
+  else if (status & DNSSEC_FAIL_NODSSUP)
+    return EDE_USUPDS;
+  else if (status & DNSSEC_FAIL_NONSEC)
+    return EDE_NO_NSEC;
+  else if (status & DNSSEC_FAIL_INDET)
+    return EDE_DNSSEC_IND;
+  else if (status & DNSSEC_FAIL_NOSIG)
+    return EDE_NO_RRSIG;
+  else
+    return EDE_UNSET;
+}
 #endif /* HAVE_DNSSEC */
diff --git a/src/domain-match.c b/src/domain-match.c
new file mode 100644 (file)
index 0000000..f8e4796
--- /dev/null
@@ -0,0 +1,698 @@
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 dated June, 1991, or
+   (at your option) version 3 dated 29 June, 2007.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+     
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "dnsmasq.h"
+
+static int order(char *qdomain, size_t qlen, struct server *serv);
+static int order_qsort(const void *a, const void *b);
+static int order_servers(struct server *s, struct server *s2);
+
+/* If the server is USE_RESOLV or LITERAL_ADDRES, it lives on the local_domains chain. */
+#define SERV_IS_LOCAL (SERV_USE_RESOLV | SERV_LITERAL_ADDRESS)
+
+void build_server_array(void)
+{
+  struct server *serv;
+  int count = 0;
+  
+  for (serv = daemon->servers; serv; serv = serv->next)
+#ifdef HAVE_LOOP
+    if (!(serv->flags & SERV_LOOP))
+#endif
+      {
+       count++;
+       if (serv->flags & SERV_WILDCARD)
+         daemon->server_has_wildcard = 1;
+      }
+  
+  for (serv = daemon->local_domains; serv; serv = serv->next)
+    {
+      count++;
+      if (serv->flags & SERV_WILDCARD)
+       daemon->server_has_wildcard = 1;
+    }
+  
+  daemon->serverarraysz = count;
+
+  if (count > daemon->serverarrayhwm)
+    {
+      struct server **new;
+
+      count += 10; /* A few extra without re-allocating. */
+
+      if ((new = whine_malloc(count * sizeof(struct server *))))
+       {
+         if (daemon->serverarray)
+           free(daemon->serverarray);
+         
+         daemon->serverarray = new;
+         daemon->serverarrayhwm = count;
+       }
+    }
+
+  count = 0;
+  
+  for (serv = daemon->servers; serv; serv = serv->next)
+#ifdef HAVE_LOOP
+    if (!(serv->flags & SERV_LOOP))
+#endif
+      {
+       daemon->serverarray[count] = serv;
+       serv->serial = count;
+       serv->last_server = -1;
+       count++;
+      }
+  
+  for (serv = daemon->local_domains; serv; serv = serv->next, count++)
+    daemon->serverarray[count] = serv;
+  
+  qsort(daemon->serverarray, daemon->serverarraysz, sizeof(struct server *), order_qsort);
+  
+  /* servers need the location in the array to find all the whole
+     set of equivalent servers from a pointer to a single one. */
+  for (count = 0; count < daemon->serverarraysz; count++)
+    if (!(daemon->serverarray[count]->flags & SERV_IS_LOCAL))
+      daemon->serverarray[count]->arrayposn = count;
+}
+
+/* we're looking for the server whose domain is the longest exact match
+   to the RH end of qdomain, or a local address if the flags match.
+   Add '.' to the LHS of the query string so
+   server=/.example.com/ works.
+
+   A flag of F_SERVER returns an upstream server only.
+   A flag of F_DNSSECOK returns a DNSSEC capable server only and
+   also disables NODOTS servers from consideration.
+   A flag of F_DOMAINSRV returns a domain-specific server only.
+   A flag of F_CONFIG returns anything that generates a local
+   reply of IPv4 or IPV6.
+   return 0 if nothing found, 1 otherwise.
+*/
+int lookup_domain(char *domain, int flags, int *lowout, int *highout)
+{
+  int rc, crop_query, nodots;
+  ssize_t qlen;
+  int try, high, low = 0;
+  int nlow = 0, nhigh = 0;
+  char *cp, *qdomain = domain;
+
+  /* may be no configured servers. */
+  if (daemon->serverarraysz == 0)
+    return 0;
+  
+  /* find query length and presence of '.' */
+  for (cp = qdomain, nodots = 1, qlen = 0; *cp; qlen++, cp++)
+    if (*cp == '.')
+      nodots = 0;
+
+  /* Handle empty name, and searches for DNSSEC queries without
+     diverting to NODOTS servers. */
+  if (qlen == 0 || flags & F_DNSSECOK)
+    nodots = 0;
+
+  /* Search shorter and shorter RHS substrings for a match */
+  while (qlen >= 0)
+    {
+      /* Note that when we chop off a label, all the possible matches
+        MUST be at a larger index than the nearest failing match with one more
+        character, since the array is sorted longest to smallest. Hence 
+        we don't reset low to zero here, we can go further below and crop the 
+        search string to the size of the largest remaining server
+        when this match fails. */
+      high = daemon->serverarraysz;
+      crop_query = 1;
+      
+      /* binary search */
+      while (1) 
+       {
+         try = (low + high)/2;
+
+         if ((rc = order(qdomain, qlen, daemon->serverarray[try])) == 0)
+           break;
+         
+         if (rc < 0)
+           {
+             if (high == try)
+               {
+                 /* qdomain is longer or same length as longest domain, and try == 0 
+                    crop the query to the longest domain. */
+                 crop_query = qlen - daemon->serverarray[try]->domain_len;
+                 break;
+               }
+             high = try;
+           }
+         else
+           {
+             if (low == try)
+               {
+                 /* try now points to the last domain that sorts before the query, so 
+                    we know that a substring of the query shorter than it is required to match, so
+                    find the largest domain that's shorter than try. Note that just going to
+                    try+1 is not optimal, consider searching bbb in (aaa,ccc,bb). try will point
+                    to aaa, since ccc sorts after bbb, but the first domain that has a chance to 
+                    match is bb. So find the length of the first domain later than try which is
+                    is shorter than it. 
+                    There's a nasty edge case when qdomain sorts before _any_ of the 
+                    server domains, where try _doesn't point_ to the last domain that sorts
+                    before the query, since no such domain exists. In that case, the loop 
+                    exits via the rc < 0 && high == try path above and this code is
+                    not executed. */
+                 ssize_t len, old = daemon->serverarray[try]->domain_len;
+                 while (++try != daemon->serverarraysz)
+                   {
+                     if (old != (len = daemon->serverarray[try]->domain_len))
+                       {
+                         crop_query = qlen - len;
+                         break;
+                       }
+                   }
+                 break;
+               }
+             low = try;
+           }
+       };
+      
+      if (rc == 0)
+       {
+         int found = 1;
+
+         if (daemon->server_has_wildcard)
+           {
+             /* if we have example.com and *example.com we need to check against *example.com, 
+                but the binary search may have found either. Use the fact that example.com is sorted before *example.com
+                We favour example.com in the case that both match (ie www.example.com) */
+             while (try != 0 && order(qdomain, qlen, daemon->serverarray[try-1]) == 0)
+               try--;
+             
+             if (!(qdomain == domain || *qdomain == 0 || *(qdomain-1) == '.'))
+               {
+                 while (try < daemon->serverarraysz-1 && order(qdomain, qlen, daemon->serverarray[try+1]) == 0)
+                   try++;
+                 
+                 if (!(daemon->serverarray[try]->flags & SERV_WILDCARD))
+                    found = 0;
+               }
+           }
+         
+         if (found)
+           {
+             /* We've matched a setting which says to use servers without a domain.
+                Continue the search with empty query */
+             if (daemon->serverarray[try]->flags & SERV_USE_RESOLV)
+               crop_query = qlen;
+             else if (filter_servers(try, flags, &nlow, &nhigh))
+               /* We have a match, but it may only be (say) an IPv6 address, and
+                  if the query wasn't for an AAAA record, it's no good, and we need
+                  to continue generalising */
+               break;
+           }
+       }
+      
+      /* crop_query must be at least one always. */
+      if (crop_query == 0)
+       crop_query = 1;
+
+      /* strip chars off the query based on the largest possible remaining match,
+        then continue to the start of the next label unless we have a wildcard
+        domain somewhere, in which case we have to go one at a time. */
+      qlen -= crop_query;
+      qdomain += crop_query;
+      if (!daemon->server_has_wildcard)
+       while (qlen > 0 &&  (*(qdomain-1) != '.'))
+         qlen--, qdomain++;
+    }
+
+  /* domain has no dots, and we have at least one server configured to handle such,
+     These servers always sort to the very end of the array. 
+     A configured server eg server=/lan/ will take precdence. */
+  if (nodots &&
+      (daemon->serverarray[daemon->serverarraysz-1]->flags & SERV_FOR_NODOTS) &&
+      (nlow == nhigh || daemon->serverarray[nlow]->domain_len == 0))
+    filter_servers(daemon->serverarraysz-1, flags, &nlow, &nhigh);
+  
+  if (lowout)
+    *lowout = nlow;
+  
+  if (highout)
+    *highout = nhigh;
+
+  if (nlow == nhigh)
+    return 0;
+
+  return 1;
+}
+
+/* Return first server in group of equivalent servers; this is the "master" record. */
+int server_samegroup(struct server *a, struct server *b)
+{
+  return order_servers(a, b) == 0;
+}
+
+int filter_servers(int seed, int flags, int *lowout, int *highout)
+{
+  int nlow = seed, nhigh = seed;
+  int i;
+  
+  /* expand nlow and nhigh to cover all the records with the same domain 
+     nlow is the first, nhigh - 1 is the last. nlow=nhigh means no servers,
+     which can happen below. */
+  while (nlow > 0 && order_servers(daemon->serverarray[nlow-1], daemon->serverarray[nlow]) == 0)
+    nlow--;
+  
+  while (nhigh < daemon->serverarraysz-1 && order_servers(daemon->serverarray[nhigh], daemon->serverarray[nhigh+1]) == 0)
+       nhigh++;
+  
+  nhigh++;
+  
+#define SERV_LOCAL_ADDRESS (SERV_6ADDR | SERV_4ADDR | SERV_ALL_ZEROS)
+  
+  if (flags & F_CONFIG)
+    {
+      /* We're just lookin for any matches that return an RR. */
+      for (i = nlow; i < nhigh; i++)
+       if (daemon->serverarray[i]->flags & SERV_LOCAL_ADDRESS)
+         break;
+      
+      /* failed, return failure. */
+      if (i == nhigh)
+       nhigh = nlow;
+    }
+  else
+    {
+      /* Now the servers are on order between low and high, in the order
+        IPv6 addr, IPv4 addr, return zero for both, send upstream, no-data return.
+        
+        See which of those match our query in that priority order and narrow (low, high) */
+
+      for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_6ADDR); i++);
+      
+      if (i != nlow && (flags & F_IPV6))
+       nhigh = i;
+      else
+       {
+         nlow = i;
+         
+         for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_4ADDR); i++);
+         
+         if (i != nlow && (flags & F_IPV4))
+           nhigh = i;
+         else
+           {
+             nlow = i;
+             
+             for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_ALL_ZEROS); i++);
+             
+             if (i != nlow && (flags & (F_IPV4 | F_IPV6)))
+               nhigh = i;
+             else
+               {
+                 nlow = i;
+                 
+                 /* now look for a server */
+                 for (i = nlow; i < nhigh && !(daemon->serverarray[i]->flags & SERV_LITERAL_ADDRESS); i++);
+
+                 if (i != nlow)
+                   {
+                     /* If we want a server that can do DNSSEC, and this one can't, 
+                        return nothing, similarly if were looking only for a server
+                        for a particular domain. */
+                     if ((flags & F_DNSSECOK) && !(daemon->serverarray[nlow]->flags & SERV_DO_DNSSEC))
+                       nlow = nhigh;
+                     else if ((flags & F_DOMAINSRV) && daemon->serverarray[nlow]->domain_len == 0)
+                       nlow = nhigh;
+                     else
+                       nhigh = i;
+                   }
+                 else
+                   {
+                     /* --local=/domain/, only return if we don't need a server. */
+                     if (flags & (F_DNSSECOK | F_DOMAINSRV | F_SERVER))
+                       nhigh = i;
+                   }
+               }
+           }
+       }
+    }
+  
+  *lowout = nlow;
+  *highout = nhigh;
+  
+  return (nlow != nhigh);
+}
+
+int is_local_answer(time_t now, int first, char *name)
+{
+  int flags = 0;
+  int rc = 0;
+  
+  if ((flags = daemon->serverarray[first]->flags) & SERV_LITERAL_ADDRESS)
+    {
+      if (flags & SERV_4ADDR)
+       rc = F_IPV4;
+      else if (flags & SERV_6ADDR)
+       rc = F_IPV6;
+      else if (flags & SERV_ALL_ZEROS)
+       rc = F_IPV4 | F_IPV6;
+      else
+       {
+         /* argument first is the first struct server which matches the query type;
+            now roll back to the server which is just the same domain, to check if that 
+            provides an answer of a different type. */
+
+         for (;first > 0 && order_servers(daemon->serverarray[first-1], daemon->serverarray[first]) == 0; first--);
+         
+         if ((daemon->serverarray[first]->flags & SERV_LOCAL_ADDRESS) ||
+             check_for_local_domain(name, now))
+           rc = F_NOERR;
+         else
+           rc = F_NXDOMAIN;
+       }
+    }
+
+  return rc;
+}
+
+size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header *header, char *name, char *limit, int first, int last, int ede)
+{
+  int trunc = 0;
+  unsigned char *p;
+  int start;
+  union all_addr addr;
+  
+  if (flags & (F_NXDOMAIN | F_NOERR))
+    log_query(flags | gotname | F_NEG | F_CONFIG | F_FORWARD, name, NULL, NULL);
+         
+  setup_reply(header, flags, ede);
+         
+  if (!(p = skip_questions(header, size)))
+    return 0;
+         
+  if (flags & gotname & F_IPV4)
+    for (start = first; start != last; start++)
+      {
+       struct serv_addr4 *srv = (struct serv_addr4 *)daemon->serverarray[start];
+
+       if (srv->flags & SERV_ALL_ZEROS)
+         memset(&addr, 0, sizeof(addr));
+       else
+         addr.addr4 = srv->addr;
+       
+       header->ancount = htons(ntohs(header->ancount) + 1);
+       add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr);
+       log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL);
+      }
+  
+  if (flags & gotname & F_IPV6)
+    for (start = first; start != last; start++)
+      {
+       struct serv_addr6 *srv = (struct serv_addr6 *)daemon->serverarray[start];
+
+       if (srv->flags & SERV_ALL_ZEROS)
+         memset(&addr, 0, sizeof(addr));
+       else
+         addr.addr6 = srv->addr;
+       
+       header->ancount = htons(ntohs(header->ancount) + 1);
+       add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr);
+       log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL);
+      }
+
+  if (trunc)
+    header->hb3 |= HB3_TC;
+
+  return p - (unsigned char *)header;
+}
+
+#ifdef HAVE_DNSSEC
+int dnssec_server(struct server *server, char *keyname, int *firstp, int *lastp)
+{
+  int first, last, index;
+
+  /* Find server to send DNSSEC query to. This will normally be the 
+     same as for the original query, but may be another if
+     servers for domains are involved. */                    
+  if (!lookup_domain(keyname, F_DNSSECOK, &first, &last))
+    return -1;
+
+  for (index = first; index != last; index++)
+    if (daemon->serverarray[index] == server)
+      break;
+             
+  /* No match to server used for original query.
+     Use newly looked up set. */
+  if (index == last)
+    index =  daemon->serverarray[first]->last_server == -1 ?
+      first : daemon->serverarray[first]->last_server;
+
+  if (firstp)
+    *firstp = first;
+
+  if (lastp)
+    *lastp = last;
+   
+  return index;
+}
+#endif
+
+/* order by size, then by dictionary order */
+static int order(char *qdomain, size_t qlen, struct server *serv)
+{
+  size_t dlen = 0;
+    
+  /* servers for dotless names always sort last 
+     searched for name is never dotless. */
+  if (serv->flags & SERV_FOR_NODOTS)
+    return -1;
+
+  dlen = serv->domain_len;
+  
+  if (qlen < dlen)
+    return 1;
+  
+  if (qlen > dlen)
+    return -1;
+
+  return strcmp(qdomain, serv->domain);
+}
+
+static int order_servers(struct server *s1, struct server *s2)
+{
+  int rc;
+
+  /* need full comparison of dotless servers in 
+     order_qsort() and filter_servers() */
+
+  if (s1->flags & SERV_FOR_NODOTS)
+     return (s2->flags & SERV_FOR_NODOTS) ? 0 : 1;
+   
+  if ((rc = order(s1->domain, s1->domain_len, s2)) != 0)
+    return rc;
+
+  /* For identical domains, sort wildcard ones first */
+  if (s1->flags & SERV_WILDCARD)
+    return (s2->flags & SERV_WILDCARD) ? 0 : 1;
+
+  return (s2->flags & SERV_WILDCARD) ? -1 : 0;
+}
+  
+static int order_qsort(const void *a, const void *b)
+{
+  int rc;
+  
+  struct server *s1 = *((struct server **)a);
+  struct server *s2 = *((struct server **)b);
+  
+  rc = order_servers(s1, s2);
+
+  /* Sort all literal NODATA and local IPV4 or IPV6 responses together,
+     in a very specific order. We flip the SERV_LITERAL_ADDRESS bit
+     so the order is IPv6 literal, IPv4 literal, all-zero literal, 
+     upstream server, NXDOMAIN literal. */
+  if (rc == 0)
+    rc = ((s2->flags & (SERV_LITERAL_ADDRESS | SERV_4ADDR | SERV_6ADDR | SERV_ALL_ZEROS)) ^ SERV_LITERAL_ADDRESS) -
+      ((s1->flags & (SERV_LITERAL_ADDRESS | SERV_4ADDR | SERV_6ADDR | SERV_ALL_ZEROS)) ^ SERV_LITERAL_ADDRESS);
+
+  /* Finally, order by appearance in /etc/resolv.conf etc, for --strict-order */
+  if (rc == 0)
+    if (!(s1->flags & SERV_LITERAL_ADDRESS))
+      rc = s1->serial - s2->serial;
+
+  return rc;
+}
+
+void mark_servers(int flag)
+{
+  struct server *serv;
+
+  /* mark everything with argument flag */
+  for (serv = daemon->servers; serv; serv = serv->next)
+    if (serv->flags & flag)
+      serv->flags |= SERV_MARK;
+    else
+      serv->flags &= ~SERV_MARK;
+
+  for (serv = daemon->local_domains; serv; serv = serv->next)
+    if (serv->flags & flag)
+      serv->flags |= SERV_MARK;
+    else
+      serv->flags &= ~SERV_MARK;
+}
+
+void cleanup_servers(void)
+{
+  struct server *serv, *tmp, **up;
+
+  /* unlink and free anything still marked. */
+  for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp) 
+    {
+      tmp = serv->next;
+      if (serv->flags & SERV_MARK)
+       {
+         server_gone(serv);
+         *up = serv->next;
+        free(serv->domain);
+        free(serv);
+       }
+      else 
+       up = &serv->next;
+    }
+  
+ for (serv = daemon->local_domains, up = &daemon->local_domains; serv; serv = tmp) 
+   {
+     tmp = serv->next;
+      if (serv->flags & SERV_MARK)
+       {
+        *up = serv->next;
+        free(serv->domain);
+        free(serv);
+       }
+      else 
+       up = &serv->next;
+   }
+}
+
+int add_update_server(int flags,
+                     union mysockaddr *addr,
+                     union mysockaddr *source_addr,
+                     const char *interface,
+                     const char *domain,
+                     union all_addr *local_addr)
+{
+  struct server *serv = NULL;
+  char *alloc_domain;
+  
+  if (!domain)
+    domain = "";
+
+  /* .domain == domain, for historical reasons. */
+  if (*domain == '.')
+    while (*domain == '.') domain++;
+  else if (*domain == '*')
+    {
+      domain++;
+      if (*domain != 0)
+       flags |= SERV_WILDCARD;
+    }
+  
+  if (*domain == 0)
+    alloc_domain = whine_malloc(1);
+  else if (!(alloc_domain = canonicalise((char *)domain, NULL)))
+    return 0;
+  
+  /* See if there is a suitable candidate, and unmark
+     only do this for forwarding servers, not 
+     address or local, to avoid delays on large numbers. */
+  if (flags & SERV_IS_LOCAL)
+    for (serv = daemon->servers; serv; serv = serv->next)
+      if ((serv->flags & SERV_MARK) &&
+         hostname_isequal(alloc_domain, serv->domain))
+       break;
+  
+  if (serv)
+    {
+      free(alloc_domain);
+      alloc_domain = serv->domain;
+    }
+  else
+    {
+      size_t size;
+
+      if (flags & SERV_LITERAL_ADDRESS)
+       {
+         if (flags & SERV_6ADDR)
+           size = sizeof(struct serv_addr6);
+         else if (flags & SERV_4ADDR)
+           size = sizeof(struct serv_addr4);
+         else
+           size = sizeof(struct serv_local);
+       }
+      else
+       size = sizeof(struct server);
+      
+      if (!(serv = whine_malloc(size)))
+       return 0;
+      
+      if (flags & SERV_IS_LOCAL)
+       {
+         serv->next = daemon->local_domains;
+         daemon->local_domains = serv;
+       }
+      else
+       {
+         struct server *s;
+         /* Add to the end of the chain, for order */
+         if (!daemon->servers)
+           daemon->servers = serv;
+         else
+           {
+             for (s = daemon->servers; s->next; s = s->next);
+             s->next = serv;
+           }
+         
+         serv->next = NULL;
+       }
+    }
+  
+  if (!(flags & SERV_IS_LOCAL))
+    memset(serv, 0, sizeof(struct server));
+  
+  serv->flags = flags;
+  serv->domain = alloc_domain;
+  serv->domain_len = strlen(alloc_domain);
+  
+  if (flags & SERV_4ADDR)
+    ((struct serv_addr4*)serv)->addr = local_addr->addr4;
+
+  if (flags & SERV_6ADDR)
+    ((struct serv_addr6*)serv)->addr = local_addr->addr6;
+  
+  if (!(flags & SERV_IS_LOCAL))
+    {
+#ifdef HAVE_LOOP
+      serv->uid = rand32();
+#endif      
+      
+      if (interface)
+       safe_strncpy(serv->interface, interface, sizeof(serv->interface));
+      if (addr)
+       serv->addr = *addr;
+      if (source_addr)
+       serv->source_addr = *source_addr;
+    }
+
+  return 1;
+}
+
index 3dc96ab..91e0f22 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -18,8 +18,9 @@
 
 
 static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c);
+static int match_domain(struct in_addr addr, struct cond_domain *c);
 static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
-
+static int match_domain6(struct in6_addr *addr, struct cond_domain *c);
 
 int is_name_synthetic(int flags, char *name, union all_addr *addr)
 {
@@ -135,28 +136,9 @@ int is_name_synthetic(int flags, char *name, union all_addr *addr)
            }
          
          if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
-           {
-             if (prot == AF_INET)
-               {
-                 if (!c->is6 &&
-                     ntohl(addr->addr4.s_addr) >= ntohl(c->start.s_addr) &&
-                     ntohl(addr->addr4.s_addr) <= ntohl(c->end.s_addr))
-                   found = 1;
-               }
-             else
-               {
-                 u64 addrpart = addr6part(&addr->addr6);
-                 
-                 if (c->is6 &&
-                     is_same_net6(&addr->addr6, &c->start6, 64) &&
-                     addrpart >= addr6part(&c->start6) &&
-                     addrpart <= addr6part(&c->end6))
-                   found = 1;
-               }
-           }
-
+           found = (prot == AF_INET) ? match_domain(addr->addr4, c) : match_domain6(&addr->addr6, c);
        }
-
+      
       /* restore name */
       for (p = tail; *p; p++)
        if (*p == '.' || *p == ':')
@@ -246,14 +228,22 @@ int is_rev_synth(int flag, union all_addr *addr, char *name)
 }
 
 
+static int match_domain(struct in_addr addr, struct cond_domain *c)
+{
+  if (!c->is6 &&
+      ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
+      ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
+    return 1;
+
+  return 0;
+}
+
 static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c)
 {
   for (; c; c = c->next)
-    if (!c->is6 &&
-       ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
-        ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
+    if (match_domain(addr, c))
       return c;
-
+  
   return NULL;
 }
 
@@ -267,16 +257,30 @@ char *get_domain(struct in_addr addr)
   return daemon->domain_suffix;
 } 
 
-
-static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
+static int match_domain6(struct in6_addr *addr, struct cond_domain *c)
 {
   u64 addrpart = addr6part(addr);
   
+  if (c->is6)
+    {
+      if (c->prefixlen >= 64)
+       {
+         if (is_same_net6(addr, &c->start6, 64) &&
+             addrpart >= addr6part(&c->start6) &&
+             addrpart <= addr6part(&c->end6))
+           return 1;
+       }
+      else if (is_same_net6(addr, &c->start6, c->prefixlen))
+       return 1;
+    }
+
+  return 0;
+}
+
+static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
+{
   for (; c; c = c->next)
-    if (c->is6 &&
-       is_same_net6(addr, &c->start6, 64) &&
-       addrpart >= addr6part(&c->start6) &&
-        addrpart <= addr6part(&c->end6))
+    if (match_domain6(addr, c))
       return c;
   
   return NULL;
index 9bd3a5f..c131953 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
index 53cfe24..7bd26b8 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -427,6 +427,66 @@ int check_source(struct dns_header *header, size_t plen, unsigned char *pseudohe
    return 1;
 }
 
+/* See https://docs.umbrella.com/umbrella-api/docs/identifying-dns-traffic for
+ * detailed information on packet formating.
+ */
+#define UMBRELLA_VERSION    1
+#define UMBRELLA_TYPESZ     2
+
+#define UMBRELLA_ASSET      0x0004
+#define UMBRELLA_ASSETSZ    sizeof(daemon->umbrella_asset)
+#define UMBRELLA_ORG        0x0008
+#define UMBRELLA_ORGSZ      sizeof(daemon->umbrella_org)
+#define UMBRELLA_IPV4       0x0010
+#define UMBRELLA_IPV6       0x0020
+#define UMBRELLA_DEVICE     0x0040
+#define UMBRELLA_DEVICESZ   sizeof(daemon->umbrella_device)
+
+struct umbrella_opt {
+  u8 magic[4];
+  u8 version;
+  u8 flags;
+  /* We have 4 possible fields since we'll never send both IPv4 and
+   * IPv6, so using the larger of the two to calculate max buffer size.
+   * Each field also has a type header.  So the following accounts for
+   * the type headers and each field size to get a max buffer size.
+   */
+  u8 fields[4 * UMBRELLA_TYPESZ + UMBRELLA_ORGSZ + IN6ADDRSZ + UMBRELLA_DEVICESZ + UMBRELLA_ASSETSZ];
+};
+
+static size_t add_umbrella_opt(struct dns_header *header, size_t plen, unsigned char *limit, union mysockaddr *source, int *cacheable)
+{
+  *cacheable = 0;
+
+  struct umbrella_opt opt = {{"ODNS"}, UMBRELLA_VERSION, 0, {}};
+  u8 *u = &opt.fields[0];
+
+  if (daemon->umbrella_org) {
+    PUTSHORT(UMBRELLA_ORG, u);
+    PUTLONG(daemon->umbrella_org, u);
+  }
+
+  int family = source->sa.sa_family;
+  PUTSHORT(family == AF_INET ? UMBRELLA_IPV4 : UMBRELLA_IPV6, u);
+  int size = family == AF_INET ? INADDRSZ : IN6ADDRSZ;
+  memcpy(u, get_addrp(source, family), size);
+  u += size;
+
+  if (option_bool(OPT_UMBRELLA_DEVID)) {
+    PUTSHORT(UMBRELLA_DEVICE, u);
+    memcpy(u, (char *)&daemon->umbrella_device, UMBRELLA_DEVICESZ);
+    u += UMBRELLA_DEVICESZ;
+  }
+
+  if (daemon->umbrella_asset) {
+    PUTSHORT(UMBRELLA_ASSET, u);
+    PUTLONG(daemon->umbrella_asset, u);
+  }
+
+  int len = u - &opt.magic[0];
+  return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, EDNS0_OPTION_UMBRELLA, (unsigned char *)&opt, len, 0, 1);
+}
+
 /* Set *check_subnet if we add a client subnet option, which needs to checked 
    in the reply. Set *cacheable to zero if we add an option which the answer
    may depend on. */
@@ -445,6 +505,9 @@ size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *l
   if (daemon->dns_client_id)
     plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMCPEID, 
                            (unsigned char *)daemon->dns_client_id, strlen(daemon->dns_client_id), 0, 1);
+
+  if (option_bool(OPT_UMBRELLA))
+    plen = add_umbrella_opt(header, plen, limit, source, cacheable);
   
   if (option_bool(OPT_CLIENT_SUBNET))
     {
index 7a95ddf..3d638e4 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #include "dnsmasq.h"
 
-static struct frec *lookup_frec(unsigned short id, int fd, int family, void *hash);
-static struct frec *lookup_frec_by_sender(unsigned short id,
-                                         union mysockaddr *addr,
-                                         void *hash);
-static struct frec *lookup_frec_by_query(void *hash, unsigned int flags);
+static struct frec *get_new_frec(time_t now, struct server *serv, int force);
+static struct frec *lookup_frec(unsigned short id, int fd, void *hash, int *firstp, int *lastp);
+static struct frec *lookup_frec_by_query(void *hash, unsigned int flags, unsigned int flagmask);
 
 static unsigned short get_id(void);
 static void free_frec(struct frec *f);
+static void query_full(time_t now, char *domain);
+
+static void return_reply(time_t now, struct frec *forward, struct dns_header *header, ssize_t n, int status);
 
 /* Send a UDP packet with its source address set as "source" 
    unless nowild is true, when we just send it with the kernel default */
@@ -108,163 +109,75 @@ int send_from(int fd, int nowild, char *packet, size_t len,
   return 1;
 }
           
-static unsigned int search_servers(time_t now, union all_addr **addrpp, unsigned int qtype,
-                                  char *qdomain, int *type, char **domain, int *norebind)
-                             
+#ifdef HAVE_CONNTRACK
+static void set_outgoing_mark(struct frec *forward, int fd)
+{
+  /* Copy connection mark of incoming query to outgoing connection. */
+  unsigned int mark;
+  if (get_incoming_mark(&forward->frec_src.source, &forward->frec_src.dest, 0, &mark))
+    setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
+}
+#endif
+
+static void log_query_mysockaddr(unsigned int flags, char *name, union mysockaddr *addr, char *arg)
+{
+  if (addr->sa.sa_family == AF_INET)
+    log_query(flags | F_IPV4, name, (union all_addr *)&addr->in.sin_addr, arg);
+  else
+    log_query(flags | F_IPV6, name, (union all_addr *)&addr->in6.sin6_addr, arg);
+}
+
+static void server_send(struct server *server, int fd,
+                       const void *header, size_t plen, int flags)
+{
+  while (retry_send(sendto(fd, header, plen, flags,
+                          &server->addr.sa,
+                          sa_len(&server->addr))));
+}
+
+#ifdef HAVE_DNSSEC
+static void server_send_log(struct server *server, int fd,
+                       const void *header, size_t plen, int dumpflags,
+                       unsigned int logflags, char *name, char *arg)
+{
+#ifdef HAVE_DUMPFILE
+         dump_packet(dumpflags, (void *)header, (size_t)plen, NULL, &server->addr);
+#endif
+         log_query_mysockaddr(logflags, name, &server->addr, arg);
+         server_send(server, fd, header, plen, 0);
+}
+#endif
+
+static int domain_no_rebind(char *domain)
 {
-  /* If the query ends in the domain in one of our servers, set
-     domain to point to that name. We find the largest match to allow both
-     domain.org and sub.domain.org to exist. */
-  
-  unsigned int namelen = strlen(qdomain);
-  unsigned int matchlen = 0;
   struct server *serv;
-  unsigned int flags = 0;
-  static union all_addr zero;
-  
-  for (serv = daemon->servers; serv; serv=serv->next)
-    if (qtype == F_DNSSECOK && !(serv->flags & SERV_DO_DNSSEC))
-      continue;
-    /* domain matches take priority over NODOTS matches */
-    else if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
-      {
-       unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6; 
-       *type = SERV_FOR_NODOTS;
-       if ((serv->flags & SERV_NO_REBIND) && norebind)
-         *norebind = 1;
-       else if (serv->flags & SERV_NO_ADDR)
-         flags = F_NXDOMAIN;
-       else if (serv->flags & SERV_LITERAL_ADDRESS)
-         { 
-           /* literal address = '#' -> return all-zero address for IPv4 and IPv6 */
-           if ((serv->flags & SERV_USE_RESOLV) && (qtype & (F_IPV6 | F_IPV4)))
-             {
-               memset(&zero, 0, sizeof(zero));
-               flags = qtype;
-               *addrpp = &zero;
-             }
-           else if (sflag & qtype)
-             {
-               flags = sflag;
-               if (serv->addr.sa.sa_family == AF_INET) 
-                 *addrpp = (union all_addr *)&serv->addr.in.sin_addr;
-               else
-                 *addrpp = (union all_addr *)&serv->addr.in6.sin6_addr;
-             }
-           else if (!flags || (flags & F_NXDOMAIN))
-             flags = F_NOERR;
-         } 
-      }
-    else if (serv->flags & SERV_HAS_DOMAIN)
-      {
-       unsigned int domainlen = strlen(serv->domain);
-       char *matchstart = qdomain + namelen - domainlen;
-       if (namelen >= domainlen &&
-           hostname_isequal(matchstart, serv->domain) &&
-           (domainlen == 0 || namelen == domainlen || *(matchstart-1) == '.' ))
-         {
-           if ((serv->flags & SERV_NO_REBIND) && norebind)     
-             *norebind = 1;
-           else
-             {
-               unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
-               /* implement priority rules for --address and --server for same domain.
-                  --address wins if the address is for the correct AF
-                  --server wins otherwise. */
-               if (domainlen != 0 && domainlen == matchlen)
-                 {
-                   if ((serv->flags & SERV_LITERAL_ADDRESS))
-                     {
-                       if (!(sflag & qtype) && flags == 0)
-                         continue;
-                     }
-                   else
-                     {
-                       if (flags & (F_IPV4 | F_IPV6))
-                         continue;
-                     }
-                 }
-               
-               if (domainlen >= matchlen)
-                 {
-                   *type = serv->flags & (SERV_HAS_DOMAIN | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_DO_DNSSEC);
-                   *domain = serv->domain;
-                   matchlen = domainlen;
-                   if (serv->flags & SERV_NO_ADDR)
-                     flags = F_NXDOMAIN;
-                   else if (serv->flags & SERV_LITERAL_ADDRESS)
-                     {
-                        /* literal address = '#' -> return all-zero address for IPv4 and IPv6 */
-                       if ((serv->flags & SERV_USE_RESOLV) && (qtype & (F_IPV6 | F_IPV4)))
-                         {                         
-                           memset(&zero, 0, sizeof(zero));
-                           flags = qtype;
-                           *addrpp = &zero;
-                         }
-                       else if (sflag & qtype)
-                         {
-                           flags = sflag;
-                           if (serv->addr.sa.sa_family == AF_INET) 
-                             *addrpp = (union all_addr *)&serv->addr.in.sin_addr;
-                           else
-                             *addrpp = (union all_addr *)&serv->addr.in6.sin6_addr;
-                         }
-                       else if (!flags || (flags & F_NXDOMAIN))
-                         flags = F_NOERR;
-                     }
-                   else
-                     flags = 0;
-                 } 
-             }
-         }
-      }
+  int dlen = (int)strlen(domain);
   
-  if (flags == 0 && !(qtype & (F_QUERY | F_DNSSECOK)) && 
-      option_bool(OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
-    /* don't forward A or AAAA queries for simple names, except the empty name */
-    flags = F_NOERR;
-  
-  if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now))
-    flags = F_NOERR;
+  for (serv = daemon->no_rebind; serv; serv = serv->next)
+    if (dlen >= serv->domain_len && strcmp(serv->domain, &domain[dlen - serv->domain_len]) == 0)
+      return 1;
 
-  if (flags)
-    {
-       if (flags == F_NXDOMAIN || flags == F_NOERR)
-        log_query(flags | qtype | F_NEG | F_CONFIG | F_FORWARD, qdomain, NULL, NULL);
-       else
-        {
-          /* handle F_IPV4 and F_IPV6 set on ANY query to 0.0.0.0/:: domain. */
-          if (flags & F_IPV4)
-            log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, qdomain, *addrpp, NULL);
-          if (flags & F_IPV6)
-            log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, qdomain, *addrpp, NULL);
-        }
-    }
-  else if ((*type) & SERV_USE_RESOLV)
-    {
-      *type = 0; /* use normal servers for this domain */
-      *domain = NULL;
-    }
-  return  flags;
+  return 0;
 }
 
 static int forward_query(int udpfd, union mysockaddr *udpaddr,
                         union all_addr *dst_addr, unsigned int dst_iface,
-                        struct dns_header *header, size_t plen, time_t now, 
+                        struct dns_header *header, size_t plen,  char *limit, time_t now, 
                         struct frec *forward, int ad_reqd, int do_bit)
 {
-  char *domain = NULL;
-  int type = SERV_DO_DNSSEC, norebind = 0;
-  union all_addr *addrp = NULL;
   unsigned int flags = 0;
   unsigned int fwd_flags = 0;
-  struct server *start = NULL;
-  void *hash = hash_questions(header, plen, daemon->namebuff);
-#ifdef HAVE_DNSSEC
-  int do_dnssec = 0;
-#endif
+  int is_dnssec = forward && (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY));
+  struct server *master;
   unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
+  void *hash = hash_questions(header, plen, daemon->namebuff);
   unsigned char *oph = find_pseudoheader(header, plen, NULL, NULL, NULL, NULL);
+  int old_src = 0;
+  int first, last, start = 0;
+  int subnet, cacheable, forwarded = 0;
+  size_t edns0_len;
+  unsigned char *pheader;
+  int ede = EDE_UNSET;
   (void)do_bit;
   
   if (header->hb4 & HB4_CD)
@@ -278,85 +191,32 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
     fwd_flags |= FREC_DO_QUESTION;
 #endif
   
-  /* may be no servers available. */
-  if (forward || (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, hash)))
+  /* Check for retry on existing query.
+     FREC_DNSKEY and FREC_DS_QUERY are never set in flags, so the test below 
+     ensures that no frec created for internal DNSSEC query can be returned here.
+     
+     Similarly FREC_NO_CACHE is never set in flags, so a query which is
+     contigent on a particular source address EDNS0 option will never be matched. */
+  if (forward)
+    old_src = 1;
+  else if ((forward = lookup_frec_by_query(hash, fwd_flags,
+                                          FREC_CHECKING_DISABLED | FREC_AD_QUESTION | FREC_DO_QUESTION |
+                                          FREC_HAS_PHEADER | FREC_DNSKEY_QUERY | FREC_DS_QUERY | FREC_NO_CACHE)))
     {
-      /* If we didn't get an answer advertising a maximal packet in EDNS,
-        fall back to 1280, which should work everywhere on IPv6.
-        If that generates an answer, it will become the new default
-        for this server */
-      forward->flags |= FREC_TEST_PKTSZ;
+      struct frec_src *src;
       
-#ifdef HAVE_DNSSEC
-      /* If we've already got an answer to this query, but we're awaiting keys for validation,
-        there's no point retrying the query, retry the key query instead...... */
-      if (forward->blocking_query)
+      for (src = &forward->frec_src; src; src = src->next)
+       if (src->orig_id == ntohs(header->id) && 
+           sockaddr_isequal(&src->source, udpaddr))
+         break;
+      
+      if (src)
+       old_src = 1;
+      else
        {
-         int fd, is_sign;
-         unsigned char *pheader;
+         /* Existing query, but from new source, just add this 
+            client to the list that will get the reply.*/
          
-         forward->flags &= ~FREC_TEST_PKTSZ;
-         
-         while (forward->blocking_query)
-           forward = forward->blocking_query;
-          
-         blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
-         plen = forward->stash_len;
-         
-         forward->flags |= FREC_TEST_PKTSZ;
-         if (find_pseudoheader(header, plen, NULL, &pheader, &is_sign, NULL) && !is_sign)
-           PUTSHORT(SAFE_PKTSZ, pheader);
-         
-         if (forward->sentto->addr.sa.sa_family == AF_INET) 
-           log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (union all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec");
-         else
-           log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (union all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec");
-
-  
-         if (forward->sentto->sfd)
-           fd = forward->sentto->sfd->fd;
-         else
-           {
-             if (forward->sentto->addr.sa.sa_family == AF_INET6)
-               fd = forward->rfd6->fd;
-             else
-               fd = forward->rfd4->fd;
-           }
-         
-         while (retry_send(sendto(fd, (char *)header, plen, 0,
-                                  &forward->sentto->addr.sa,
-                                  sa_len(&forward->sentto->addr))));
-         
-         return 1;
-       }
-#endif
-
-      /* retry on existing query, send to all available servers  */
-      domain = forward->sentto->domain;
-      forward->sentto->failed_queries++;
-      if (!option_bool(OPT_ORDER))
-       {
-         forward->forwardall = 1;
-         daemon->last_server = NULL;
-       }
-      type = forward->sentto->flags & SERV_TYPE;
-#ifdef HAVE_DNSSEC
-      do_dnssec = forward->sentto->flags & SERV_DO_DNSSEC;
-#endif
-
-      if (!(start = forward->sentto->next))
-       start = daemon->servers; /* at end of list, recycle */
-      header->id = htons(forward->new_id);
-    }
-  else 
-    {
-      /* Query from new source, but the same query may be in progress
-        from another source. If so, just add this client to the
-        list that will get the reply.*/
-        
-      if (!option_bool(OPT_ADD_MAC) && !option_bool(OPT_MAC_B64) &&
-         (forward = lookup_frec_by_query(hash, fwd_flags)))
-       {
          /* Note whine_malloc() zeros memory. */
          if (!daemon->free_frec_src &&
              daemon->frec_src_count < daemon->ftabsize &&
@@ -366,269 +226,345 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
              daemon->free_frec_src->next = NULL;
            }
          
-         /* If we've been spammed with many duplicates, just drop the query. */
-         if (daemon->free_frec_src)
+         /* If we've been spammed with many duplicates, return REFUSED. */
+         if (!daemon->free_frec_src)
            {
-             struct frec_src *new = daemon->free_frec_src;
-             daemon->free_frec_src = new->next;
-             new->next = forward->frec_src.next;
-             forward->frec_src.next = new;
-             new->orig_id = ntohs(header->id);
-             new->source = *udpaddr;
-             new->dest = *dst_addr;
-             new->log_id = daemon->log_id;
-             new->iface = dst_iface;
+             query_full(now, NULL);
+             goto reply;
            }
          
-         return 1;
+         src = daemon->free_frec_src;
+         daemon->free_frec_src = src->next;
+         src->next = forward->frec_src.next;
+         forward->frec_src.next = src;
+         src->orig_id = ntohs(header->id);
+         src->source = *udpaddr;
+         src->dest = *dst_addr;
+         src->log_id = daemon->log_id;
+         src->iface = dst_iface;
+         src->fd = udpfd;
+
+         /* closely spaced identical queries cannot be a try and a retry, so
+            it's safe to wait for the reply from the first without
+            forwarding the second. */
+         if (difftime(now, forward->time) < 2)
+           return 0;
        }
-       
-      if (gotname)
-       flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
+    }
+
+  /* new query */
+  if (!forward)
+    {
+      if (lookup_domain(daemon->namebuff, gotname, &first, &last))
+       flags = is_local_answer(now, first, daemon->namebuff);
+      else
+       {
+         /* no available server. */
+         ede = EDE_NOT_READY;
+         flags = 0;
+       }
+       
+      /* don't forward A or AAAA queries for simple names, except the empty name */
+      if (!flags &&
+         option_bool(OPT_NODOTS_LOCAL) &&
+         (gotname & (F_IPV4 | F_IPV6)) &&
+         !strchr(daemon->namebuff, '.') &&
+         strlen(daemon->namebuff) != 0)
+       flags = check_for_local_domain(daemon->namebuff, now) ? F_NOERR : F_NXDOMAIN;
       
-#ifdef HAVE_DNSSEC
-      do_dnssec = type & SERV_DO_DNSSEC;
-#endif
-      type &= ~SERV_DO_DNSSEC;      
+      /* Configured answer. */
+      if (flags || ede == EDE_NOT_READY)
+       goto reply;
       
-      if (daemon->servers && !flags)
-       forward = get_new_frec(now, NULL, NULL);
+      master = daemon->serverarray[first];
+      
+      if (!(forward = get_new_frec(now, master, 0)))
+       goto reply;
       /* table full - flags == 0, return REFUSED */
       
-      if (forward)
+      forward->frec_src.source = *udpaddr;
+      forward->frec_src.orig_id = ntohs(header->id);
+      forward->frec_src.dest = *dst_addr;
+      forward->frec_src.iface = dst_iface;
+      forward->frec_src.next = NULL;
+      forward->frec_src.fd = udpfd;
+      forward->new_id = get_id();
+      memcpy(forward->hash, hash, HASH_SIZE);
+      forward->forwardall = 0;
+      forward->flags = fwd_flags;
+      if (domain_no_rebind(daemon->namebuff))
+       forward->flags |= FREC_NOREBIND;
+      if (header->hb4 & HB4_CD)
+       forward->flags |= FREC_CHECKING_DISABLED;
+      if (ad_reqd)
+       forward->flags |= FREC_AD_QUESTION;
+#ifdef HAVE_DNSSEC
+      forward->work_counter = DNSSEC_WORK;
+      if (do_bit)
+       forward->flags |= FREC_DO_QUESTION;
+#endif
+      
+      start = first;
+
+      if (option_bool(OPT_ALL_SERVERS))
+       forward->forwardall = 1;
+
+      if (!option_bool(OPT_ORDER))
        {
-         forward->frec_src.source = *udpaddr;
-         forward->frec_src.orig_id = ntohs(header->id);
-         forward->frec_src.dest = *dst_addr;
-         forward->frec_src.iface = dst_iface;
-         forward->frec_src.next = NULL;
-         forward->new_id = get_id();
-         forward->fd = udpfd;
-         memcpy(forward->hash, hash, HASH_SIZE);
-         forward->forwardall = 0;
-         forward->flags = fwd_flags;
-         if (norebind)
-           forward->flags |= FREC_NOREBIND;
-         if (header->hb4 & HB4_CD)
-           forward->flags |= FREC_CHECKING_DISABLED;
-         if (ad_reqd)
-           forward->flags |= FREC_AD_QUESTION;
+         if (master->forwardcount++ > FORWARD_TEST ||
+             difftime(now, master->forwardtime) > FORWARD_TIME ||
+             master->last_server == -1)
+           {
+             master->forwardtime = now;
+             master->forwardcount = 0;
+             forward->forwardall = 1;
+           }
+         else
+           start = master->last_server;
+       }
+    }
+  else
+    {
+      /* retry on existing query, from original source. Send to all available servers  */
 #ifdef HAVE_DNSSEC
-         forward->work_counter = DNSSEC_WORK;
-         if (do_bit)
-           forward->flags |= FREC_DO_QUESTION;
+      /* If we've already got an answer to this query, but we're awaiting keys for validation,
+        there's no point retrying the query, retry the key query instead...... */
+      if (forward->blocking_query)
+       {
+         int is_sign;
+         unsigned char *pheader;
+         
+         while (forward->blocking_query)
+           forward = forward->blocking_query;
+          
+         blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
+         plen = forward->stash_len;
+         /* get query for logging. */
+         extract_request(header, plen, daemon->namebuff, NULL);
+         
+         if (find_pseudoheader(header, plen, NULL, &pheader, &is_sign, NULL) && !is_sign)
+           PUTSHORT(SAFE_PKTSZ, pheader);
+         
+         /* Find suitable servers: should never fail. */
+         if (!filter_servers(forward->sentto->arrayposn, F_DNSSECOK, &first, &last))
+           return 0;
+         
+         is_dnssec = 1;
+         forward->forwardall = 1;
+       }
+      else
 #endif
+       {
+         /* retry on existing query, from original source. Send to all available servers  */
+         forward->sentto->failed_queries++;
          
-         header->id = htons(forward->new_id);
+         if (!filter_servers(forward->sentto->arrayposn, F_SERVER, &first, &last))
+           goto reply;
          
-         /* In strict_order mode, always try servers in the order 
-            specified in resolv.conf, if a domain is given 
-            always try all the available servers,
-            otherwise, use the one last known to work. */
+         master = daemon->serverarray[first];
          
-         if (type == 0)
+         /* Forward to all available servers on retry of query from same host. */
+         if (!option_bool(OPT_ORDER) && old_src)
+           forward->forwardall = 1;
+         else
            {
+             start = forward->sentto->arrayposn;
+             
              if (option_bool(OPT_ORDER))
-               start = daemon->servers;
-             else if (!(start = daemon->last_server) ||
-                      daemon->forwardcount++ > FORWARD_TEST ||
-                      difftime(now, daemon->forwardtime) > FORWARD_TIME)
                {
-                 start = daemon->servers;
-                 forward->forwardall = 1;
-                 daemon->forwardcount = 0;
-                 daemon->forwardtime = now;
+                 /* In strict order mode, there must be a server later in the list
+                    left to send to, otherwise without the forwardall mechanism,
+                    code further on will cycle around the list forwever if they
+                    all return REFUSED. If at the last, give up. */
+                 if (++start == last)
+                   goto reply;
                }
-           }
-         else
-           {
-             start = daemon->servers;
-             if (!option_bool(OPT_ORDER))
-               forward->forwardall = 1;
-           }
+           }     
        }
+      
+      /* If we didn't get an answer advertising a maximal packet in EDNS,
+        fall back to 1280, which should work everywhere on IPv6.
+        If that generates an answer, it will become the new default
+        for this server */
+      forward->flags |= FREC_TEST_PKTSZ;
     }
 
-  /* check for send errors here (no route to host) 
-     if we fail to send to all nameservers, send back an error
-     packet straight away (helps modem users when offline)  */
-  
-  if (!flags && forward)
+  /* If a query is retried, use the log_id for the retry when logging the answer. */
+  forward->frec_src.log_id = daemon->log_id;
+
+  /* We may be resending a DNSSEC query here, for which the below processing is not necessary. */
+  if (!is_dnssec)
     {
-      struct server *firstsentto = start;
-      int subnet, cacheable, forwarded = 0;
-      size_t edns0_len;
-      unsigned char *pheader;
-      
-      /* If a query is retried, use the log_id for the retry when logging the answer. */
-      forward->frec_src.log_id = daemon->log_id;
+      header->id = htons(forward->new_id);
       
       plen = add_edns0_config(header, plen, ((unsigned char *)header) + PACKETSZ, &forward->frec_src.source, now, &subnet, &cacheable);
       
       if (subnet)
        forward->flags |= FREC_HAS_SUBNET;
-
+      
       if (!cacheable)
        forward->flags |= FREC_NO_CACHE;
-
+      
 #ifdef HAVE_DNSSEC
-      if (option_bool(OPT_DNSSEC_VALID) && do_dnssec)
+      if (option_bool(OPT_DNSSEC_VALID) && (master->flags & SERV_DO_DNSSEC))
        {
          plen = add_do_bit(header, plen, ((unsigned char *) header) + PACKETSZ);
-                     
+         
          /* For debugging, set Checking Disabled, otherwise, have the upstream check too,
             this allows it to select auth servers when one is returning bad data. */
          if (option_bool(OPT_DNSSEC_DEBUG))
            header->hb4 |= HB4_CD;
-
+         
        }
 #endif
-
+      
       if (find_pseudoheader(header, plen, &edns0_len, &pheader, NULL, NULL))
        {
          /* If there wasn't a PH before, and there is now, we added it. */
          if (!oph)
            forward->flags |= FREC_ADDED_PHEADER;
-
+         
          /* If we're sending an EDNS0 with any options, we can't recreate the query from a reply. */
          if (edns0_len > 11)
            forward->flags |= FREC_HAS_EXTRADATA;
-
+         
          /* Reduce udp size on retransmits. */
          if (forward->flags & FREC_TEST_PKTSZ)
            PUTSHORT(SAFE_PKTSZ, pheader);
        }
-      
-      while (1)
-       { 
-         /* only send to servers dealing with our domain.
-            domain may be NULL, in which case server->domain 
-            must be NULL also. */
-         
-         if (type == (start->flags & SERV_TYPE) &&
-             (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
-             !(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
-           {
-             int fd;
+    }
+  
+  if (forward->forwardall)
+    start = first;
 
-             /* find server socket to use, may need to get random one. */
-             if (start->sfd)
-               fd = start->sfd->fd;
-             else 
-               {
-                 if (start->addr.sa.sa_family == AF_INET6)
-                   {
-                     if (!forward->rfd6 &&
-                         !(forward->rfd6 = allocate_rfd(AF_INET6)))
-                       break;
-                     daemon->rfd_save = forward->rfd6;
-                     fd = forward->rfd6->fd;
-                   }
-                 else
-                   {
-                     if (!forward->rfd4 &&
-                         !(forward->rfd4 = allocate_rfd(AF_INET)))
-                       break;
-                     daemon->rfd_save = forward->rfd4;
-                     fd = forward->rfd4->fd;
-                   }
+  forwarded = 0;
+  
+  /* check for send errors here (no route to host) 
+     if we fail to send to all nameservers, send back an error
+     packet straight away (helps modem users when offline)  */
 
+  while (1)
+    { 
+      int fd;
+      struct server *srv = daemon->serverarray[start];
+      
+      if ((fd = allocate_rfd(&forward->rfds, srv)) != -1)
+       {
+         
 #ifdef HAVE_CONNTRACK
-                 /* Copy connection mark of incoming query to outgoing connection. */
-                 if (option_bool(OPT_CONNTRACK))
-                   {
-                     unsigned int mark;
-                     if (get_incoming_mark(&forward->frec_src.source, &forward->frec_src.dest, 0, &mark))
-                       setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
-                   }
+         /* Copy connection mark of incoming query to outgoing connection. */
+         if (option_bool(OPT_CONNTRACK))
+           set_outgoing_mark(forward, fd);
 #endif
-               }
-             
+         
 #ifdef HAVE_DNSSEC
-             if (option_bool(OPT_DNSSEC_VALID) && (forward->flags & FREC_ADDED_PHEADER))
-               {
-                 /* Difficult one here. If our client didn't send EDNS0, we will have set the UDP
-                    packet size to 512. But that won't provide space for the RRSIGS in many cases.
-                    The RRSIGS will be stripped out before the answer goes back, so the packet should
-                    shrink again. So, if we added a do-bit, bump the udp packet size to the value
-                    known to be OK for this server. We check returned size after stripping and set
-                    the truncated bit if it's still too big. */                  
-                 unsigned char *pheader;
-                 int is_sign;
-                 if (find_pseudoheader(header, plen, NULL, &pheader, &is_sign, NULL) && !is_sign)
-                   PUTSHORT(start->edns_pktsz, pheader);
-               }
+         if (option_bool(OPT_DNSSEC_VALID) && (forward->flags & FREC_ADDED_PHEADER))
+           {
+             /* Difficult one here. If our client didn't send EDNS0, we will have set the UDP
+                packet size to 512. But that won't provide space for the RRSIGS in many cases.
+                The RRSIGS will be stripped out before the answer goes back, so the packet should
+                shrink again. So, if we added a do-bit, bump the udp packet size to the value
+                known to be OK for this server. We check returned size after stripping and set
+                the truncated bit if it's still too big. */              
+             unsigned char *pheader;
+             int is_sign;
+             if (find_pseudoheader(header, plen, NULL, &pheader, &is_sign, NULL) && !is_sign)
+               PUTSHORT(srv->edns_pktsz, pheader);
+           }
 #endif
-
-             if (retry_send(sendto(fd, (char *)header, plen, 0,
-                                   &start->addr.sa,
-                                   sa_len(&start->addr))))
-               continue;
-           
-             if (errno == 0)
-               {
+         
+         if (retry_send(sendto(fd, (char *)header, plen, 0,
+                               &srv->addr.sa,
+                               sa_len(&srv->addr))))
+           continue;
+         
+         if (errno == 0)
+           {
 #ifdef HAVE_DUMPFILE
-                 dump_packet(DUMP_UP_QUERY, (void *)header, plen, NULL, &start->addr);
+             dump_packet(DUMP_UP_QUERY, (void *)header, plen, NULL, &srv->addr);
 #endif
-                 
-                 /* Keep info in case we want to re-send this packet */
-                 daemon->srv_save = start;
-                 daemon->packet_len = plen;
-                 
+             
+             /* Keep info in case we want to re-send this packet */
+             daemon->srv_save = srv;
+             daemon->packet_len = plen;
+             daemon->fd_save = fd;
+             
+             if (!(forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)))
+               {
                  if (!gotname)
                    strcpy(daemon->namebuff, "query");
-                 if (start->addr.sa.sa_family == AF_INET)
-                   log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 
-                             (union all_addr *)&start->addr.in.sin_addr, NULL); 
-                 else
-                   log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 
-                             (union  all_addr *)&start->addr.in6.sin6_addr, NULL);
-                 start->queries++;
-                 forwarded = 1;
-                 forward->sentto = start;
-                 if (!forward->forwardall) 
-                   break;
-                 forward->forwardall++;
+                 log_query_mysockaddr(F_SERVER | F_FORWARD, daemon->namebuff,
+                                      &srv->addr, NULL);
                }
-           } 
-         
-         if (!(start = start->next))
-           start = daemon->servers;
-         
-         if (start == firstsentto)
-           break;
+#ifdef HAVE_DNSSEC
+             else
+               log_query_mysockaddr(F_NOEXTRA | F_DNSSEC, daemon->namebuff, &srv->addr,
+                                    querystr("dnssec-retry", (forward->flags & FREC_DNSKEY_QUERY) ? T_DNSKEY : T_DS));
+#endif
+
+             srv->queries++;
+             forwarded = 1;
+             forward->sentto = srv;
+             if (!forward->forwardall) 
+               break;
+             forward->forwardall++;
+           }
        }
       
-      if (forwarded)
-       return 1;
-      
-      /* could not send on, prepare to return */ 
-      header->id = htons(forward->frec_src.orig_id);
-      free_frec(forward); /* cancel */
-    }    
+      if (++start == last)
+       break;
+    }
+  
+  if (forwarded || is_dnssec)
+    return 1;
   
-  /* could not send on, return empty answer or address if known for whole domain */
+  /* could not send on, prepare to return */ 
+  header->id = htons(forward->frec_src.orig_id);
+  free_frec(forward); /* cancel */
+  ede = EDE_NETERR;
+  
+ reply:
   if (udpfd != -1)
     {
-      plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
+      if (!(plen = make_local_answer(flags, gotname, plen, header, daemon->namebuff, limit, first, last, ede)))
+       return 0;
+      
       if (oph)
-       plen = add_pseudoheader(header, plen, ((unsigned char *) header) + PACKETSZ, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
+       {
+         u16 swap = htons((u16)ede);
+
+         if (ede != EDE_UNSET)
+           plen = add_pseudoheader(header, plen, (unsigned char *)limit, daemon->edns_pktsz, EDNS0_OPTION_EDE, (unsigned char *)&swap, 2, do_bit, 0);
+         else
+           plen = add_pseudoheader(header, plen, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
+       }
+      
+#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
+      if (option_bool(OPT_CMARK_ALST_EN))
+       {
+         unsigned int mark;
+         int have_mark = get_incoming_mark(udpaddr, dst_addr, /* istcp: */ 0, &mark);
+         if (have_mark && ((u32)mark & daemon->allowlist_mask))
+           report_addresses(header, plen, mark);
+       }
+#endif
+      
       send_from(udpfd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), (char *)header, plen, udpaddr, dst_addr, dst_iface);
     }
-
+         
   return 0;
 }
 
 static size_t process_reply(struct dns_header *header, time_t now, struct server *server, size_t n, int check_rebind, 
                            int no_cache, int cache_secure, int bogusanswer, int ad_reqd, int do_bit, int added_pheader, 
-                           int check_subnet, union mysockaddr *query_source)
+                           int check_subnet, union mysockaddr *query_source, unsigned char *limit, int ede)
 {
   unsigned char *pheader, *sizep;
   char **sets = 0;
   int munged = 0, is_sign;
   unsigned int rcode = RCODE(header);
   size_t plen; 
-  
+    
   (void)ad_reqd;
   (void)do_bit;
   (void)bogusanswer;
@@ -676,11 +612,10 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
            }
          else
            {
-             unsigned short udpsz;
-
              /* If upstream is advertising a larger UDP packet size
                 than we allow, trim it so that we don't get overlarge
                 requests for the client. We can't do this for signed packets. */
+             unsigned short udpsz;
              GETSHORT(udpsz, sizep);
              if (udpsz > daemon->edns_pktsz)
                {
@@ -707,7 +642,9 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
   /* RFC 4035 sect 4.6 para 3 */
   if (!is_sign && !option_bool(OPT_DNSSEC_PROXY))
      header->hb4 &= ~HB4_AD;
-  
+
+  header->hb4 |= HB4_RA; /* recursion if available */
+
   if (OPCODE(header) != QUERY)
     return resize_packet(header, n, pheader, plen);
 
@@ -715,6 +652,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
     {
       union all_addr a;
       a.log.rcode = rcode;
+      a.log.ede = ede;
       log_query(F_UPSTREAM | F_RCODE, "error", &a, NULL);
       
       return resize_packet(header, n, pheader, plen);
@@ -731,28 +669,32 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
     }  
 
   if (daemon->bogus_addr && rcode != NXDOMAIN &&
-      check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
+      check_for_bogus_wildcard(header, n, daemon->namebuff, now))
     {
       munged = 1;
       SET_RCODE(header, NXDOMAIN);
       header->hb3 &= ~HB3_AA;
       cache_secure = 0;
+      ede = EDE_BLOCKED;
     }
   else 
     {
       int doctored = 0;
       
       if (rcode == NXDOMAIN && 
-         extract_request(header, n, daemon->namebuff, NULL) &&
-         check_for_local_domain(daemon->namebuff, now))
+         extract_request(header, n, daemon->namebuff, NULL))
        {
-         /* if we forwarded a query for a locally known name (because it was for 
-            an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
-            since we know that the domain exists, even if upstream doesn't */
-         munged = 1;
-         header->hb3 |= HB3_AA;
-         SET_RCODE(header, NOERROR);
-         cache_secure = 0;
+         if (check_for_local_domain(daemon->namebuff, now) ||
+             lookup_domain(daemon->namebuff, F_CONFIG, NULL, NULL))
+           {
+             /* if we forwarded a query for a locally known name (because it was for 
+                an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
+                since we know that the domain exists, even if upstream doesn't */
+             munged = 1;
+             header->hb3 |= HB3_AA;
+             SET_RCODE(header, NOERROR);
+             cache_secure = 0;
+           }
        }
       
       if (extract_addresses(header, n, daemon->namebuff, now, sets, is_sign, check_rebind, no_cache, cache_secure, &doctored))
@@ -760,6 +702,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
          my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
          munged = 1;
          cache_secure = 0;
+         ede = EDE_BLOCKED;
        }
 
       if (doctored)
@@ -789,7 +732,6 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
 
   /* do this after extract_addresses. Ensure NODATA reply and remove
      nameserver info. */
-  
   if (munged)
     {
       header->ancount = htons(0);
@@ -801,11 +743,189 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
   /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
      sections of the packet. Find the new length here and put back pseudoheader
      if it was removed. */
-  return resize_packet(header, n, pheader, plen);
+  n = resize_packet(header, n, pheader, plen);
+
+  if (pheader && ede != EDE_UNSET)
+    {
+      u16 swap = htons((u16)ede);
+      n = add_pseudoheader(header, n, limit, daemon->edns_pktsz, EDNS0_OPTION_EDE, (unsigned char *)&swap, 2, do_bit, 1);
+    }
+  
+  return n;
+}
+
+#ifdef HAVE_DNSSEC
+static void dnssec_validate(struct frec *forward, struct dns_header *header,
+                           ssize_t plen, int status, time_t now)
+{
+  daemon->log_display_id = forward->frec_src.log_id;
+  
+  /* We've had a reply already, which we're validating. Ignore this duplicate */
+  if (forward->blocking_query)
+    return;
+  
+  /* Truncated answer can't be validated.
+     If this is an answer to a DNSSEC-generated query, we still
+     need to get the client to retry over TCP, so return
+     an answer with the TC bit set, even if the actual answer fits.
+  */
+  if (header->hb3 & HB3_TC)
+    status = STAT_TRUNCATED;
+
+  /* If all replies to a query are REFUSED, give up. */
+  if (RCODE(header) == REFUSED)
+    status = STAT_ABANDONED;
+  
+  /* As soon as anything returns BOGUS, we stop and unwind, to do otherwise
+     would invite infinite loops, since the answers to DNSKEY and DS queries
+     will not be cached, so they'll be repeated. */
+  if (!STAT_ISEQUAL(status, STAT_BOGUS) && !STAT_ISEQUAL(status, STAT_TRUNCATED) && !STAT_ISEQUAL(status, STAT_ABANDONED))
+    {
+      if (forward->flags & FREC_DNSKEY_QUERY)
+       status = dnssec_validate_by_ds(now, header, plen, daemon->namebuff, daemon->keyname, forward->class);
+      else if (forward->flags & FREC_DS_QUERY)
+       status = dnssec_validate_ds(now, header, plen, daemon->namebuff, daemon->keyname, forward->class);
+      else
+       status = dnssec_validate_reply(now, header, plen, daemon->namebuff, daemon->keyname, &forward->class, 
+                                      !option_bool(OPT_DNSSEC_IGN_NS) && (forward->sentto->flags & SERV_DO_DNSSEC),
+                                      NULL, NULL, NULL);
+#ifdef HAVE_DUMPFILE
+      if (STAT_ISEQUAL(status, STAT_BOGUS))
+       dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_BOGUS : DUMP_BOGUS,
+                   header, (size_t)plen, &forward->sentto->addr, NULL);
+#endif
+    }
+  
+  /* Can't validate, as we're missing key data. Put this
+     answer aside, whilst we get that. */     
+  if (STAT_ISEQUAL(status, STAT_NEED_DS) || STAT_ISEQUAL(status, STAT_NEED_KEY))
+    {
+      struct frec *new = NULL;
+      int serverind;
+      struct blockdata *stash;
+      
+      /* Now save reply pending receipt of key data */
+      if ((serverind = dnssec_server(forward->sentto, daemon->keyname, NULL, NULL)) != -1 &&
+         (stash = blockdata_alloc((char *)header, plen)))
+       {
+         struct server *server = daemon->serverarray[serverind];
+         struct frec *orig;
+         unsigned int flags;
+         void *hash;
+         size_t nn;
+
+         /* validate routines leave name of required record in daemon->keyname */
+         nn = dnssec_generate_query(header, ((unsigned char *) header) + server->edns_pktsz,
+                                    daemon->keyname, forward->class,
+                                    STAT_ISEQUAL(status, STAT_NEED_KEY) ? T_DNSKEY : T_DS, server->edns_pktsz);
+         
+         flags = STAT_ISEQUAL(status, STAT_NEED_KEY) ? FREC_DNSKEY_QUERY : FREC_DS_QUERY;
+         hash = hash_questions(header, nn, daemon->namebuff);
+
+         if ((new = lookup_frec_by_query(hash, flags, FREC_DNSKEY_QUERY | FREC_DS_QUERY)))
+           {
+             forward->next_dependent = new->dependent;
+             new->dependent = forward;
+             /* Make consistent, only replace query copy with unvalidated answer
+                when we set ->blocking_query. */
+             if (forward->stash)
+               blockdata_free(forward->stash);
+             forward->blocking_query = new;
+             forward->stash_len = plen;
+             forward->stash = stash;
+             return;
+           }
+           
+         /* Find the original query that started it all.... */
+         for (orig = forward; orig->dependent; orig = orig->dependent);
+         
+         /* Make sure we don't expire and free the orig frec during the
+            allocation of a new one: third arg of get_new_frec() does that. */
+         if (--orig->work_counter == 0 || !(new = get_new_frec(now, server, 1)))
+           blockdata_free(stash); /* don't leak this on failure. */
+         else
+           {
+             int fd;
+             struct frec *next = new->next;
+
+             *new = *forward; /* copy everything, then overwrite */
+             new->next = next;
+             new->blocking_query = NULL;
+             
+             new->frec_src.log_id = daemon->log_display_id = ++daemon->log_id;
+             new->sentto = server;
+             new->rfds = NULL;
+             new->frec_src.next = NULL;
+             new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY | FREC_HAS_EXTRADATA);
+             new->flags |= flags;
+             new->forwardall = 0;
+             
+             forward->next_dependent = NULL;
+             new->dependent = forward; /* to find query awaiting new one. */
+
+             /* Make consistent, only replace query copy with unvalidated answer
+                when we set ->blocking_query. */
+             forward->blocking_query = new; 
+             if (forward->stash)
+               blockdata_free(forward->stash);
+             forward->stash_len = plen;
+             forward->stash = stash;
+             
+             memcpy(new->hash, hash, HASH_SIZE);
+             new->new_id = get_id();
+             header->id = htons(new->new_id);
+             /* Save query for retransmission */
+             new->stash = blockdata_alloc((char *)header, nn);
+             new->stash_len = nn;
+             
+             /* Don't resend this. */
+             daemon->srv_save = NULL;
+             
+             if ((fd = allocate_rfd(&new->rfds, server)) != -1)
+               {
+#ifdef HAVE_CONNTRACK
+                 if (option_bool(OPT_CONNTRACK))
+                   set_outgoing_mark(orig, fd);
+#endif
+                 server_send_log(server, fd, header, nn, DUMP_SEC_QUERY,
+                                 F_NOEXTRA | F_DNSSEC, daemon->keyname,
+                                 querystr("dnssec-query", STAT_ISEQUAL(status, STAT_NEED_KEY) ? T_DNSKEY : T_DS));
+                 server->queries++;
+               }
+             
+             return;
+           }
+       }
+
+      /* sending DNSSEC query failed. */
+      status = STAT_ABANDONED;
+    }
+  
+  /* Validated original answer, all done. */
+  if (!forward->dependent)
+    return_reply(now, forward, header, plen, status);
+  else
+    {
+      /* validated subsidiary query/queries, (and cached result)
+        pop that and return to the previous query/queries we were working on. */
+      struct frec *prev, *nxt = forward->dependent;
+      
+      free_frec(forward);
+      
+      while ((prev = nxt))
+       {
+         /* ->next_dependent will have changed after return from recursive call below. */
+         nxt = prev->next_dependent;
+         prev->blocking_query = NULL; /* already gone */
+         blockdata_retrieve(prev->stash, prev->stash_len, (void *)header);
+         dnssec_validate(prev, header, prev->stash_len, status, now);
+       }
+    }
 }
+#endif
 
 /* sets new last_server */
-void reply_query(int fd, int family, time_t now)
+void reply_query(int fd, time_t now)
 {
   /* packet from peer server, extract data for cache, and send to
      original requester */
@@ -814,40 +934,48 @@ void reply_query(int fd, int family, time_t now)
   struct frec *forward;
   socklen_t addrlen = sizeof(serveraddr);
   ssize_t n = recvfrom(fd, daemon->packet, daemon->packet_buff_sz, 0, &serveraddr.sa, &addrlen);
-  size_t nn;
   struct server *server;
   void *hash;
-
+  int first, last, c;
+    
   /* packet buffer overwritten */
   daemon->srv_save = NULL;
-  
+
   /* Determine the address of the server replying  so that we can mark that as good */
-  if ((serveraddr.sa.sa_family = family) == AF_INET6)
+  if (serveraddr.sa.sa_family == AF_INET6)
     serveraddr.in6.sin6_flowinfo = 0;
   
   header = (struct dns_header *)daemon->packet;
 
   if (n < (int)sizeof(struct dns_header) || !(header->hb3 & HB3_QR))
     return;
+
+  hash = hash_questions(header, n, daemon->namebuff);
+  
+  if (!(forward = lookup_frec(ntohs(header->id), fd, hash, &first, &last)))
+    return;
   
-  /* spoof check: answer must come from known server, */
-  for (server = daemon->servers; server; server = server->next)
-    if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
-       sockaddr_isequal(&server->addr, &serveraddr))
+  /* spoof check: answer must come from known server, also
+     we may have sent the same query to multiple servers from
+     the same local socket, and would like to know which one has answered. */
+  for (c = first; c != last; c++)
+    if (sockaddr_isequal(&daemon->serverarray[c]->addr, &serveraddr))
       break;
   
-  if (!server)
+  if (c == last)
     return;
 
+  server = daemon->serverarray[c];
+
+  if (RCODE(header) != REFUSED)
+    daemon->serverarray[first]->last_server = c;
+  else if (daemon->serverarray[first]->last_server == c)
+    daemon->serverarray[first]->last_server = -1;
+
   /* If sufficient time has elapsed, try and expand UDP buffer size again. */
   if (difftime(now, server->pktsz_reduced) > UDP_TEST_TIME)
     server->edns_pktsz = daemon->edns_pktsz;
 
-  hash = hash_questions(header, n, daemon->namebuff);
-  
-  if (!(forward = lookup_frec(ntohs(header->id), fd, family, hash)))
-    return;
-  
 #ifdef HAVE_DUMPFILE
   dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY,
              (void *)header, n, &serveraddr, NULL);
@@ -859,7 +987,7 @@ void reply_query(int fd, int family, time_t now)
   daemon->log_source_addr = &forward->frec_src.source;
   
   if (daemon->ignore_addr && RCODE(header) == NOERROR &&
-      check_for_ignored_address(header, n, daemon->ignore_addr))
+      check_for_ignored_address(header, n))
     return;
 
   /* Note: if we send extra options in the EDNS0 header, we can't recreate
@@ -869,453 +997,262 @@ void reply_query(int fd, int family, time_t now)
       !(forward->flags & FREC_HAS_EXTRADATA))
     /* for broken servers, attempt to send to another one. */
     {
-      unsigned char *pheader;
+      unsigned char *pheader, *udpsz;
+      unsigned short udp_size =  PACKETSZ; /* default if no EDNS0 */
       size_t plen;
       int is_sign;
-
+      size_t nn = 0;
+      
 #ifdef HAVE_DNSSEC
-      if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY))
+      /* DNSSEC queries have a copy of the original query stashed. 
+        The query MAY have got a good answer, and be awaiting
+        the results of further queries, in which case
+        The Stash contains something else and we don't need to retry anyway. */
+      if ((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) && !forward->blocking_query)
        {
-         struct server *start;
-         
          blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
-         plen = forward->stash_len;
-
-         forward->forwardall = 2; /* only retry once */
-         start = forward->sentto;
-
-         /* for non-domain specific servers, see if we can find another to try. */
-         if ((forward->sentto->flags & SERV_TYPE) == 0)
-           while (1)
-             {
-               if (!(start = start->next))
-                 start = daemon->servers;
-               if (start == forward->sentto)
-                 break;
-               
-               if ((start->flags & SERV_TYPE) == 0 &&
-                   (start->flags & SERV_DO_DNSSEC))
-                 break;
-             }
-           
-         
-         fd = -1;
-
-         if (start->sfd)
-           fd = start->sfd->fd;
-         else
-           {
-             if (start->addr.sa.sa_family == AF_INET6)
-               {
-                 /* may have changed family */
-                 if (forward->rfd6 || (forward->rfd6 = allocate_rfd(AF_INET6)))
-                   fd = forward->rfd6->fd;
-               }
-             else
-               {
-                 /* may have changed family */
-                 if (forward->rfd4 || (forward->rfd4 = allocate_rfd(AF_INET)))
-                   fd = forward->rfd4->fd;
-               }
-           }
-
-         /* Can't get socket. */
-         if (fd == -1)
-           return;
-         
-#ifdef HAVE_DUMPFILE
-         dump_packet(DUMP_SEC_QUERY, (void *)header, (size_t)plen, NULL, &start->addr);
+         nn = forward->stash_len;
+         udp_size = daemon->edns_pktsz;
+       }
+      else
 #endif
-
-         while (retry_send(sendto(fd, (char *)header, plen, 0,
-                                  &start->addr.sa,
-                                  sa_len(&start->addr))));
+       {
+         /* recreate query from reply */
+         if ((pheader = find_pseudoheader(header, (size_t)n, &plen, &udpsz, &is_sign, NULL)))
+           GETSHORT(udp_size, udpsz);
          
-         if (start->addr.sa.sa_family == AF_INET) 
-           log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (union all_addr *)&start->addr.in.sin_addr, "dnssec");
-         else
-           log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (union all_addr *)&start->addr.in6.sin6_addr, "dnssec");
+         /* If the client provides an EDNS0 UDP size, use that to limit our reply.
+            (bounded by the maximum configured). If no EDNS0, then it
+            defaults to 512 */
+         if (udp_size > daemon->edns_pktsz)
+           udp_size = daemon->edns_pktsz;
+         else if (udp_size < PACKETSZ)
+           udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */
          
-         return;
-       }
-#endif
-      
-      /* In strict order mode, there must be a server later in the chain
-        left to send to, otherwise without the forwardall mechanism,
-        code further on will cycle around the list forwever if they
-        all return REFUSED. Note that server is always non-NULL before 
-        this executes. */
-      if (option_bool(OPT_ORDER))
-       for (server = forward->sentto->next; server; server = server->next)
-         if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR | SERV_LOOP)))
-           break;
+         if (!is_sign &&
+             (nn = resize_packet(header, (size_t)n, pheader, plen)) &&
+             (forward->flags & FREC_DO_QUESTION))
+           add_do_bit(header, nn,  (unsigned char *)pheader + plen);
 
-      /* recreate query from reply */
-      pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign, NULL);
-      if (!is_sign && server)
-       {
          header->ancount = htons(0);
          header->nscount = htons(0);
          header->arcount = htons(0);
-         if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
-           {
-             header->hb3 &= ~(HB3_QR | HB3_AA | HB3_TC);
-             header->hb4 &= ~(HB4_RA | HB4_RCODE | HB4_CD | HB4_AD);
-             if (forward->flags & FREC_CHECKING_DISABLED)
-               header->hb4 |= HB4_CD;
-             if (forward->flags & FREC_AD_QUESTION)
-               header->hb4 |= HB4_AD;
-             if (forward->flags & FREC_DO_QUESTION)
-               add_do_bit(header, nn,  (unsigned char *)pheader + plen);
-             forward_query(-1, NULL, NULL, 0, header, nn, now, forward, forward->flags & FREC_AD_QUESTION, forward->flags & FREC_DO_QUESTION);
-             return;
-           }
+         header->hb3 &= ~(HB3_QR | HB3_AA | HB3_TC);
+         header->hb4 &= ~(HB4_RA | HB4_RCODE | HB4_CD | HB4_AD);
+         if (forward->flags & FREC_CHECKING_DISABLED)
+           header->hb4 |= HB4_CD;
+         if (forward->flags & FREC_AD_QUESTION)
+           header->hb4 |= HB4_AD;
        }
-    }   
-   
-  server = forward->sentto;
-  if ((forward->sentto->flags & SERV_TYPE) == 0)
-    {
-      if (RCODE(header) == REFUSED)
-       server = NULL;
-      else
+
+      if (nn)
        {
-         struct server *last_server;
-         
-         /* find good server by address if possible, otherwise assume the last one we sent to */ 
-         for (last_server = daemon->servers; last_server; last_server = last_server->next)
-           if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
-               sockaddr_isequal(&last_server->addr, &serveraddr))
-             {
-               server = last_server;
-               break;
-             }
-       } 
-      if (!option_bool(OPT_ALL_SERVERS))
-       daemon->last_server = server;
+         forward_query(-1, NULL, NULL, 0, header, nn, ((char *) header) + udp_size, now, forward,
+                       forward->flags & FREC_AD_QUESTION, forward->flags & FREC_DO_QUESTION);
+         return;
+       }
     }
+
+  /* If the answer is an error, keep the forward record in place in case
+     we get a good reply from another server. Kill it when we've
+     had replies from all to avoid filling the forwarding table when
+     everything is broken */
+
+  /* decrement count of replies recieved if we sent to more than one server. */
+  if (forward->forwardall && (--forward->forwardall > 1) && RCODE(header) == REFUSED)
+    return;
+
   /* We tried resending to this server with a smaller maximum size and got an answer.
      Make that permanent. To avoid reduxing the packet size for a single dropped packet,
      only do this when we get a truncated answer, or one larger than the safe size. */
-  if (forward->sentto->edns_pktsz > SAFE_PKTSZ && (forward->flags & FREC_TEST_PKTSZ) && 
+  if (server->edns_pktsz > SAFE_PKTSZ && (forward->flags & FREC_TEST_PKTSZ) && 
       ((header->hb3 & HB3_TC) || n >= SAFE_PKTSZ))
     {
-      forward->sentto->edns_pktsz = SAFE_PKTSZ;
-      forward->sentto->pktsz_reduced = now;
-      (void)prettyprint_addr(&forward->sentto->addr, daemon->addrbuff);
+      server->edns_pktsz = SAFE_PKTSZ;
+      server->pktsz_reduced = now;
+      (void)prettyprint_addr(&server->addr, daemon->addrbuff);
       my_syslog(LOG_WARNING, _("reducing DNS packet size for nameserver %s to %d"), daemon->addrbuff, SAFE_PKTSZ);
     }
 
-    
-  /* If the answer is an error, keep the forward record in place in case
-     we get a good reply from another server. Kill it when we've
-     had replies from all to avoid filling the forwarding table when
-     everything is broken */
-  if (forward->forwardall == 0 || --forward->forwardall == 1 || RCODE(header) != REFUSED)
+  forward->sentto = server;
+  
+#ifdef HAVE_DNSSEC
+  if ((forward->sentto->flags & SERV_DO_DNSSEC) && 
+      option_bool(OPT_DNSSEC_VALID) &&
+      !(forward->flags & FREC_CHECKING_DISABLED))
+    dnssec_validate(forward, header, n, STAT_OK, now);
+  else
+#endif
+    return_reply(now, forward, header, n, STAT_OK); 
+}
+
+static void return_reply(time_t now, struct frec *forward, struct dns_header *header, ssize_t n, int status)
+{
+  int check_rebind = 0, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0;
+  size_t nn;
+  int ede = EDE_UNSET;
+
+  (void)status;
+
+  daemon->log_display_id = forward->frec_src.log_id;
+  daemon->log_source_addr = &forward->frec_src.source;
+  
+  /* Don't cache replies where DNSSEC validation was turned off, either
+     the upstream server told us so, or the original query specified it.  */
+  if ((header->hb4 & HB4_CD) || (forward->flags & FREC_CHECKING_DISABLED))
+    no_cache_dnssec = 1;
+
+#ifdef HAVE_DNSSEC
+  if (!STAT_ISEQUAL(status, STAT_OK))
     {
-      int check_rebind = 0, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0;
+      /* status is STAT_OK when validation not turned on. */
+      no_cache_dnssec = 0;
       
-      if (option_bool(OPT_NO_REBIND))
-       check_rebind = !(forward->flags & FREC_NOREBIND);
-      
-      /*   Don't cache replies where DNSSEC validation was turned off, either
-          the upstream server told us so, or the original query specified it.  */
-      if ((header->hb4 & HB4_CD) || (forward->flags & FREC_CHECKING_DISABLED))
-       no_cache_dnssec = 1;
-      
-#ifdef HAVE_DNSSEC
-      if ((forward->sentto->flags & SERV_DO_DNSSEC) && 
-         option_bool(OPT_DNSSEC_VALID) && !(forward->flags & FREC_CHECKING_DISABLED))
+      if (STAT_ISEQUAL(status, STAT_TRUNCATED))
+       header->hb3 |= HB3_TC;
+      else
        {
-         int status = 0;
-
-         /* We've had a reply already, which we're validating. Ignore this duplicate */
-         if (forward->blocking_query)
-           return;
-         
-          /* Truncated answer can't be validated.
-             If this is an answer to a DNSSEC-generated query, we still
-             need to get the client to retry over TCP, so return
-             an answer with the TC bit set, even if the actual answer fits.
-          */
-         if (header->hb3 & HB3_TC)
-           status = STAT_TRUNCATED;
-         
-         while (1)
-           {
-             /* As soon as anything returns BOGUS, we stop and unwind, to do otherwise
-                would invite infinite loops, since the answers to DNSKEY and DS queries
-                will not be cached, so they'll be repeated. */
-             if (status != STAT_BOGUS && status != STAT_TRUNCATED && status != STAT_ABANDONED)
-               {
-                 if (forward->flags & FREC_DNSKEY_QUERY)
-                   status = dnssec_validate_by_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
-                 else if (forward->flags & FREC_DS_QUERY)
-                   status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
-                 else
-                   status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class, 
-                                                  !option_bool(OPT_DNSSEC_IGN_NS) && (forward->sentto->flags & SERV_DO_DNSSEC),
-                                                  NULL, NULL, NULL);
-#ifdef HAVE_DUMPFILE
-                 if (status == STAT_BOGUS)
-                   dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_BOGUS : DUMP_BOGUS,
-                               header, (size_t)n, &serveraddr, NULL);
-#endif
-               }
-             
-             /* Can't validate, as we're missing key data. Put this
-                answer aside, whilst we get that. */     
-             if (status == STAT_NEED_DS || status == STAT_NEED_KEY)
-               {
-                 struct frec *new, *orig;
-                 
-                 /* Free any saved query */
-                 if (forward->stash)
-                   blockdata_free(forward->stash);
-                 
-                 /* Now save reply pending receipt of key data */
-                 if (!(forward->stash = blockdata_alloc((char *)header, n)))
-                   return;
-                 forward->stash_len = n;
-                 
-                 /* Find the original query that started it all.... */
-                 for (orig = forward; orig->dependent; orig = orig->dependent);
-                 
-                 /* Make sure we don't expire and free the orig frec during the
-                    allocation of a new one. */
-                 if (--orig->work_counter == 0 || !(new = get_new_frec(now, NULL, orig)))
-                   status = STAT_ABANDONED;
-                 else
-                   {
-                     int querytype, fd, type = SERV_DO_DNSSEC;
-                     struct frec *next = new->next;
-                     char *domain;
-                     
-                     *new = *forward; /* copy everything, then overwrite */
-                     new->next = next;
-                     new->blocking_query = NULL;
-
-                     /* Find server to forward to. This will normally be the 
-                        same as for the original query, but may be another if
-                        servers for domains are involved. */                 
-                     if (search_servers(now, NULL, F_DNSSECOK, daemon->keyname, &type, &domain, NULL) == 0)
-                       {
-                         struct server *start, *new_server = NULL;
-                         start = server = forward->sentto;
-                         
-                         while (1)
-                           {
-                             if (type == (start->flags & (SERV_TYPE | SERV_DO_DNSSEC)) &&
-                                 ((type & SERV_TYPE) != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
-                                 !(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
-                               {
-                                 new_server = start;
-                                 if (server == start)
-                                   {
-                                     new_server = NULL;
-                                     break;
-                                   }
-                               }
-                             
-                             if (!(start = start->next))
-                               start = daemon->servers;
-                             if (start == server)
-                               break;
-                           }
-                         
-                         if (new_server)
-                           server = new_server;
-                       }
-                     
-                     new->sentto = server;
-                     new->rfd4 = NULL;
-                     new->rfd6 = NULL;
-                     new->frec_src.next = NULL;
-                     new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY | FREC_HAS_EXTRADATA);
-                     new->forwardall = 0;
-                     
-                     new->dependent = forward; /* to find query awaiting new one. */
-                     forward->blocking_query = new; /* for garbage cleaning */
-                     /* validate routines leave name of required record in daemon->keyname */
-                     if (status == STAT_NEED_KEY)
-                       {
-                         new->flags |= FREC_DNSKEY_QUERY; 
-                         querytype = T_DNSKEY;
-                       }
-                     else 
-                       {
-                         new->flags |= FREC_DS_QUERY;
-                         querytype = T_DS;
-                       }
+         char *result, *domain = "result";
+         union all_addr a;
 
-                     nn = dnssec_generate_query(header,((unsigned char *) header) + server->edns_pktsz,
-                                                daemon->keyname, forward->class, querytype, server->edns_pktsz);
+         a.log.ede = ede = errflags_to_ede(status);
 
-                     if (server->addr.sa.sa_family == AF_INET) 
-                       log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, daemon->keyname, (union all_addr *)&(server->addr.in.sin_addr),
-                                 querystr("dnssec-query", querytype));
-                     else
-                       log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, daemon->keyname, (union all_addr *)&(server->addr.in6.sin6_addr),
-                                 querystr("dnssec-query", querytype));
-  
-                     memcpy(new->hash, hash_questions(header, nn, daemon->namebuff), HASH_SIZE);
-                     new->new_id = get_id();
-                     header->id = htons(new->new_id);
-                     /* Save query for retransmission */
-                     new->stash = blockdata_alloc((char *)header, nn);
-                     new->stash_len = nn;
-                     
-                     /* Don't resend this. */
-                     daemon->srv_save = NULL;
-                     
-                     if (server->sfd)
-                       fd = server->sfd->fd;
-                     else
-                       {
-                         fd = -1;
-                         if (server->addr.sa.sa_family == AF_INET6)
-                           {
-                             if (new->rfd6 || (new->rfd6 = allocate_rfd(AF_INET6)))
-                               fd = new->rfd6->fd;
-                           }
-                         else
-                           {
-                             if (new->rfd4 || (new->rfd4 = allocate_rfd(AF_INET)))
-                               fd = new->rfd4->fd;
-                           }
-                       }
-                     
-                     if (fd != -1)
-                       {
-#ifdef HAVE_CONNTRACK
-                         /* Copy connection mark of incoming query to outgoing connection. */
-                         if (option_bool(OPT_CONNTRACK))
-                           {
-                             unsigned int mark;
-                             if (get_incoming_mark(&orig->frec_src.source, &orig->frec_src.dest, 0, &mark))
-                               setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
-                           }
-#endif
-                         
-#ifdef HAVE_DUMPFILE
-                         dump_packet(DUMP_SEC_QUERY, (void *)header, (size_t)nn, NULL, &server->addr);
-#endif
-                         
-                         while (retry_send(sendto(fd, (char *)header, nn, 0, 
-                                                  &server->addr.sa, 
-                                                  sa_len(&server->addr)))); 
-                         server->queries++;
-                       }
-                   }             
-                 return;
-               }
-         
-             /* Validated original answer, all done. */
-             if (!forward->dependent)
-               break;
-             
-             /* validated subsidiary query, (and cached result)
-                pop that and return to the previous query we were working on. */
-             struct frec *prev = forward->dependent;
-             free_frec(forward);
-             forward = prev;
-             forward->blocking_query = NULL; /* already gone */
-             blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
-             n = forward->stash_len;
-           }
-       
-         
-         no_cache_dnssec = 0;
-         
-         if (status == STAT_TRUNCATED)
-           header->hb3 |= HB3_TC;
-         else
+         if (STAT_ISEQUAL(status, STAT_ABANDONED))
            {
-             char *result, *domain = "result";
-             
-             if (status == STAT_ABANDONED)
-               {
-                 result = "ABANDONED";
-                 status = STAT_BOGUS;
-               }
-             else
-               result = (status == STAT_SECURE ? "SECURE" : (status == STAT_INSECURE ? "INSECURE" : "BOGUS"));
-             
-             if (status == STAT_BOGUS && extract_request(header, n, daemon->namebuff, NULL))
-               domain = daemon->namebuff;
-             
-             log_query(F_SECSTAT, domain, NULL, result);
+             result = "ABANDONED";
+             status = STAT_BOGUS;
            }
+         else
+           result = (STAT_ISEQUAL(status, STAT_SECURE) ? "SECURE" : (STAT_ISEQUAL(status, STAT_INSECURE) ? "INSECURE" : "BOGUS"));
          
-         if (status == STAT_SECURE)
+         if (STAT_ISEQUAL(status, STAT_SECURE))
            cache_secure = 1;
-         else if (status == STAT_BOGUS)
+         else if (STAT_ISEQUAL(status, STAT_BOGUS))
            {
              no_cache_dnssec = 1;
              bogusanswer = 1;
+             
+             if (extract_request(header, n, daemon->namebuff, NULL))
+               domain = daemon->namebuff;
            }
+         
+         log_query(F_SECSTAT, domain, &a, result);
        }
-
+    }
 #endif
-
-      /* restore CD bit to the value in the query */
-      if (forward->flags & FREC_CHECKING_DISABLED)
-       header->hb4 |= HB4_CD;
-      else
-       header->hb4 &= ~HB4_CD;
-
-      /* Never cache answers which are contingent on the source or MAC address EDSN0 option,
-        since the cache is ignorant of such things. */
-      if (forward->flags & FREC_NO_CACHE)
-       no_cache_dnssec = 1;
+  
+  if (option_bool(OPT_NO_REBIND))
+    check_rebind = !(forward->flags & FREC_NOREBIND);
+  
+  /* restore CD bit to the value in the query */
+  if (forward->flags & FREC_CHECKING_DISABLED)
+    header->hb4 |= HB4_CD;
+  else
+    header->hb4 &= ~HB4_CD;
+  
+  /* Never cache answers which are contingent on the source or MAC address EDSN0 option,
+     since the cache is ignorant of such things. */
+  if (forward->flags & FREC_NO_CACHE)
+    no_cache_dnssec = 1;
+  
+  if ((nn = process_reply(header, now, forward->sentto, (size_t)n, check_rebind, no_cache_dnssec, cache_secure, bogusanswer, 
+                         forward->flags & FREC_AD_QUESTION, forward->flags & FREC_DO_QUESTION, 
+                         forward->flags & FREC_ADDED_PHEADER, forward->flags & FREC_HAS_SUBNET, &forward->frec_src.source,
+                         ((unsigned char *)header) + daemon->edns_pktsz, ede)))
+    {
+      struct frec_src *src;
       
-      if ((nn = process_reply(header, now, forward->sentto, (size_t)n, check_rebind, no_cache_dnssec, cache_secure, bogusanswer, 
-                             forward->flags & FREC_AD_QUESTION, forward->flags & FREC_DO_QUESTION, 
-                             forward->flags & FREC_ADDED_PHEADER, forward->flags & FREC_HAS_SUBNET, &forward->frec_src.source)))
-       {
-         struct frec_src *src;
-
-         header->id = htons(forward->frec_src.orig_id);
-         header->hb4 |= HB4_RA; /* recursion if available */
+      header->id = htons(forward->frec_src.orig_id);
 #ifdef HAVE_DNSSEC
-         /* We added an EDNSO header for the purpose of getting DNSSEC RRs, and set the value of the UDP payload size
-            greater than the no-EDNS0-implied 512 to have space for the RRSIGS. If, having stripped them and the EDNS0
-             header, the answer is still bigger than 512, truncate it and mark it so. The client then retries with TCP. */
-         if (option_bool(OPT_DNSSEC_VALID) && (forward->flags & FREC_ADDED_PHEADER) && (nn > PACKETSZ))
+      /* We added an EDNSO header for the purpose of getting DNSSEC RRs, and set the value of the UDP payload size
+        greater than the no-EDNS0-implied 512 to have space for the RRSIGS. If, having stripped them and the EDNS0
+        header, the answer is still bigger than 512, truncate it and mark it so. The client then retries with TCP. */
+      if (option_bool(OPT_DNSSEC_VALID) && (forward->flags & FREC_ADDED_PHEADER) && (nn > PACKETSZ))
+       {
+         header->ancount = htons(0);
+         header->nscount = htons(0);
+         header->arcount = htons(0);
+         header->hb3 |= HB3_TC;
+         nn = resize_packet(header, nn, NULL, 0);
+       }
+#endif
+      
+      for (src = &forward->frec_src; src; src = src->next)
+       {
+         header->id = htons(src->orig_id);
+         
+#ifdef HAVE_DUMPFILE
+         dump_packet(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &src->source);
+#endif
+         
+#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
+         if (option_bool(OPT_CMARK_ALST_EN))
            {
-             header->ancount = htons(0);
-             header->nscount = htons(0);
-             header->arcount = htons(0);
-             header->hb3 |= HB3_TC;
-             nn = resize_packet(header, nn, NULL, 0);
+             unsigned int mark;
+             int have_mark = get_incoming_mark(&src->source, &src->dest, /* istcp: */ 0, &mark);
+             if (have_mark && ((u32)mark & daemon->allowlist_mask))
+               report_addresses(header, nn, mark);
            }
 #endif
-
-         for (src = &forward->frec_src; src; src = src->next)
+         
+         send_from(src->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn, 
+                   &src->source, &src->dest, src->iface);
+         
+         if (option_bool(OPT_EXTRALOG) && src != &forward->frec_src)
            {
-             header->id = htons(src->orig_id);
-             
-#ifdef HAVE_DUMPFILE
-             dump_packet(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &src->source);
-#endif
-             
-             send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn, 
-                       &src->source, &src->dest, src->iface);
-
-             if (option_bool(OPT_EXTRALOG) && src != &forward->frec_src)
-               {
-                 daemon->log_display_id = src->log_id;
-                 daemon->log_source_addr = &src->source;
-                 log_query(F_UPSTREAM, "query", NULL, "duplicate");
-               }
+             daemon->log_display_id = src->log_id;
+             daemon->log_source_addr = &src->source;
+             log_query(F_UPSTREAM, "query", NULL, "duplicate");
            }
        }
-
-      free_frec(forward); /* cancel */
     }
+
+  free_frec(forward); /* cancel */
+}
+
+
+#ifdef HAVE_CONNTRACK
+static int is_query_allowed_for_mark(u32 mark, const char *name)
+{
+  int is_allowable_name, did_validate_name = 0;
+  struct allowlist *allowlists;
+  char **patterns_pos;
+  
+  for (allowlists = daemon->allowlists; allowlists; allowlists = allowlists->next)
+    if (allowlists->mark == (mark & daemon->allowlist_mask & allowlists->mask))
+      for (patterns_pos = allowlists->patterns; *patterns_pos; patterns_pos++)
+       {
+         if (!strcmp(*patterns_pos, "*"))
+           return 1;
+         if (!did_validate_name)
+           {
+             is_allowable_name = name ? is_valid_dns_name(name) : 0;
+             did_validate_name = 1;
+           }
+         if (is_allowable_name && is_dns_name_matching_pattern(name, *patterns_pos))
+           return 1;
+       }
+  return 0;
 }
 
+static size_t answer_disallowed(struct dns_header *header, size_t qlen, u32 mark, const char *name)
+{
+  unsigned char *p;
+  (void)name;
+  (void)mark;
+  
+#ifdef HAVE_UBUS
+  if (name)
+    ubus_event_bcast_connmark_allowlist_refused(mark, name);
+#endif
+  
+  setup_reply(header, /* flags: */ 0, EDE_BLOCKED);
+  
+  if (!(p = skip_questions(header, qlen)))
+    return 0;
+  return p - (unsigned char *)header;
+}
+#endif
 
 void receive_query(struct listener *listen, time_t now)
 {
@@ -1328,6 +1265,11 @@ void receive_query(struct listener *listen, time_t now)
   size_t m;
   ssize_t n;
   int if_index = 0, auth_dns = 0, do_bit = 0, have_pseudoheader = 0;
+#ifdef HAVE_CONNTRACK
+  unsigned int mark = 0;
+  int have_mark = 0;
+  int is_single_query = 0, allowed = 1;
+#endif
 #ifdef HAVE_AUTH
   int local_auth = 0;
 #endif
@@ -1353,7 +1295,7 @@ void receive_query(struct listener *listen, time_t now)
 
   /* packet buffer overwritten */
   daemon->srv_save = NULL;
-  
+
   dst_addr_4.s_addr = dst_addr.addr4.s_addr = 0;
   netmask.s_addr = 0;
   
@@ -1556,6 +1498,11 @@ void receive_query(struct listener *listen, time_t now)
 #ifdef HAVE_DUMPFILE
   dump_packet(DUMP_QUERY, daemon->packet, (size_t)n, &source_addr, NULL);
 #endif
+  
+#ifdef HAVE_CONNTRACK
+  if (option_bool(OPT_CMARK_ALST_EN))
+    have_mark = get_incoming_mark(&source_addr, &dst_addr, /* istcp: */ 0, &mark);
+#endif
          
   if (extract_request(header, (size_t)n, daemon->namebuff, &type))
     {
@@ -1563,13 +1510,13 @@ void receive_query(struct listener *listen, time_t now)
       struct auth_zone *zone;
 #endif
       char *types = querystr(auth_dns ? "auth" : "query", type);
+
+      log_query_mysockaddr(F_QUERY | F_FORWARD, daemon->namebuff,
+                          &source_addr, types);
       
-      if (family == AF_INET) 
-       log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 
-                 (union all_addr *)&source_addr.in.sin_addr, types);
-      else
-       log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 
-                 (union all_addr *)&source_addr.in6.sin6_addr, types);
+#ifdef HAVE_CONNTRACK
+      is_single_query = 1;
+#endif
 
 #ifdef HAVE_AUTH
       /* find queries for zones we're authoritative for, and answer them directly */
@@ -1611,76 +1558,226 @@ void receive_query(struct listener *listen, time_t now)
        udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */
     }
 
+#ifdef HAVE_CONNTRACK
+#ifdef HAVE_AUTH
+  if (!auth_dns || local_auth)
+#endif
+    if (option_bool(OPT_CMARK_ALST_EN) && have_mark && ((u32)mark & daemon->allowlist_mask))
+      allowed = is_query_allowed_for_mark((u32)mark, is_single_query ? daemon->namebuff : NULL);
+#endif
+  
+  if (0);
+#ifdef HAVE_CONNTRACK
+  else if (!allowed)
+    {
+      u16 swap = htons(EDE_BLOCKED);
+
+      m = answer_disallowed(header, (size_t)n, (u32)mark, is_single_query ? daemon->namebuff : NULL);
+      
+      if (have_pseudoheader && m != 0)
+       m = add_pseudoheader(header,  m,  ((unsigned char *) header) + udp_size, daemon->edns_pktsz,
+                            EDNS0_OPTION_EDE, (unsigned char *)&swap, 2, do_bit, 0);
+      
+      if (m >= 1)
+       {
+#ifdef HAVE_DUMPFILE
+         dump_packet(DUMP_REPLY, daemon->packet, m, NULL, &source_addr);
+#endif
+         send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
+                   (char *)header, m, &source_addr, &dst_addr, if_index);
+         daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]++;
+       }
+    }
+#endif
 #ifdef HAVE_AUTH
-  if (auth_dns)
+  else if (auth_dns)
     {
       m = answer_auth(header, ((char *) header) + udp_size, (size_t)n, now, &source_addr, 
                      local_auth, do_bit, have_pseudoheader);
       if (m >= 1)
        {
+#ifdef HAVE_DUMPFILE
+         dump_packet(DUMP_REPLY, daemon->packet, m, NULL, &source_addr);
+#endif
+#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
+         if (local_auth)
+           if (option_bool(OPT_CMARK_ALST_EN) && have_mark && ((u32)mark & daemon->allowlist_mask))
+             report_addresses(header, m, mark);
+#endif
          send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
                    (char *)header, m, &source_addr, &dst_addr, if_index);
          daemon->metrics[METRIC_DNS_AUTH_ANSWERED]++;
        }
     }
-  else
 #endif
+  else
     {
       int ad_reqd = do_bit;
-       /* RFC 6840 5.7 */
+      /* RFC 6840 5.7 */
       if (header->hb4 & HB4_AD)
        ad_reqd = 1;
-
+      
       m = answer_request(header, ((char *) header) + udp_size, (size_t)n, 
                         dst_addr_4, netmask, now, ad_reqd, do_bit, have_pseudoheader);
       
       if (m >= 1)
        {
+#ifdef HAVE_DUMPFILE
+         dump_packet(DUMP_REPLY, daemon->packet, m, NULL, &source_addr);
+#endif
+#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
+         if (option_bool(OPT_CMARK_ALST_EN) && have_mark && ((u32)mark & daemon->allowlist_mask))
+           report_addresses(header, m, mark);
+#endif
          send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
                    (char *)header, m, &source_addr, &dst_addr, if_index);
          daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]++;
        }
       else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
-                            header, (size_t)n, now, NULL, ad_reqd, do_bit))
+                            header, (size_t)n,  ((char *) header) + udp_size, now, NULL, ad_reqd, do_bit))
        daemon->metrics[METRIC_DNS_QUERIES_FORWARDED]++;
       else
        daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]++;
     }
 }
 
+/* Send query in packet, qsize to a server determined by first,last,start and
+   get the reply. return reply size. */
+static ssize_t tcp_talk(int first, int last, int start, unsigned char *packet,  size_t qsize,
+                       int have_mark, unsigned int mark, struct server **servp)
+{
+  int firstsendto = -1;
+  u16 *length = (u16 *)packet;
+  unsigned char *payload = &packet[2];
+  struct dns_header *header = (struct dns_header *)payload;
+  unsigned char c1, c2;
+  unsigned char hash[HASH_SIZE];
+  unsigned int rsize;
+  
+  (void)mark;
+  (void)have_mark;
+
+  memcpy(hash, hash_questions(header, (unsigned int)qsize, daemon->namebuff), HASH_SIZE);
+  
+  while (1) 
+    {
+      int data_sent = 0;
+      struct server *serv;
+      
+      if (firstsendto == -1)
+       firstsendto = start;
+      else
+       {
+         start++;
+         
+         if (start == last)
+           start = first;
+         
+         if (start == firstsendto)
+           break;
+       }
+      
+      serv = daemon->serverarray[start];
+      
+    retry:
+      *length = htons(qsize);
+      
+      if (serv->tcpfd == -1)
+       {
+         if ((serv->tcpfd = socket(serv->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
+           continue;
+         
+#ifdef HAVE_CONNTRACK
+         /* Copy connection mark of incoming query to outgoing connection. */
+         if (have_mark)
+           setsockopt(serv->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
+#endif                   
+         
+         if ((!local_bind(serv->tcpfd,  &serv->source_addr, serv->interface, 0, 1)))
+           {
+             close(serv->tcpfd);
+             serv->tcpfd = -1;
+             continue;
+           }
+         
+#ifdef MSG_FASTOPEN
+         server_send(serv, serv->tcpfd, packet, qsize + sizeof(u16), MSG_FASTOPEN);
+         
+         if (errno == 0)
+           data_sent = 1;
+#endif
+         
+         if (!data_sent && connect(serv->tcpfd, &serv->addr.sa, sa_len(&serv->addr)) == -1)
+           {
+             close(serv->tcpfd);
+             serv->tcpfd = -1;
+             continue;
+           }
+         
+         daemon->serverarray[first]->last_server = start;
+         serv->flags &= ~SERV_GOT_TCP;
+       }
+      
+      if ((!data_sent && !read_write(serv->tcpfd, packet, qsize + sizeof(u16), 0)) ||
+         !read_write(serv->tcpfd, &c1, 1, 1) ||
+         !read_write(serv->tcpfd, &c2, 1, 1) ||
+         !read_write(serv->tcpfd, payload, (rsize = (c1 << 8) | c2), 1))
+       {
+         close(serv->tcpfd);
+         serv->tcpfd = -1;
+         /* We get data then EOF, reopen connection to same server,
+            else try next. This avoids DoS from a server which accepts
+            connections and then closes them. */
+         if (serv->flags & SERV_GOT_TCP)
+           goto retry;
+         else
+           continue;
+       }
+
+      /* If the hash of the question section doesn't match the crc we sent, then
+        someone might be attempting to insert bogus values into the cache by 
+        sending replies containing questions and bogus answers. 
+        Try another server, or give up */
+      if (memcmp(hash, hash_questions(header, rsize, daemon->namebuff), HASH_SIZE) != 0)
+       continue;
+      
+      serv->flags |= SERV_GOT_TCP;
+      
+      *servp = serv;
+      return rsize;
+    }
+
+  return 0;
+}
+                 
 #ifdef HAVE_DNSSEC
-/* Recurse up the key hierarchy */
+/* Recurse down the key hierarchy */
 static int tcp_key_recurse(time_t now, int status, struct dns_header *header, size_t n, 
                           int class, char *name, char *keyname, struct server *server, 
                           int have_mark, unsigned int mark, int *keycount)
 {
-  int new_status;
+  int first, last, start, new_status;
   unsigned char *packet = NULL;
-  unsigned char *payload = NULL;
   struct dns_header *new_header = NULL;
-  u16 *length = NULL;
+  
   while (1)
     {
-      int type = SERV_DO_DNSSEC;
-      char *domain;
-      size_t m; 
-      unsigned char c1, c2;
-      struct server *firstsendto = NULL;
-      
+      size_t m;
+      int log_save;
+            
       /* limit the amount of work we do, to avoid cycling forever on loops in the DNS */
       if (--(*keycount) == 0)
        new_status = STAT_ABANDONED;
-      else if (status == STAT_NEED_KEY)
+      else if (STAT_ISEQUAL(status, STAT_NEED_KEY))
        new_status = dnssec_validate_by_ds(now, header, n, name, keyname, class);
-      else if (status == STAT_NEED_DS)
+      else if (STAT_ISEQUAL(status, STAT_NEED_DS))
        new_status = dnssec_validate_ds(now, header, n, name, keyname, class);
       else 
        new_status = dnssec_validate_reply(now, header, n, name, keyname, &class,
                                           !option_bool(OPT_DNSSEC_IGN_NS) && (server->flags & SERV_DO_DNSSEC),
                                           NULL, NULL, NULL);
       
-      if (new_status != STAT_NEED_DS && new_status != STAT_NEED_KEY)
+      if (!STAT_ISEQUAL(new_status, STAT_NEED_DS) && !STAT_ISEQUAL(new_status, STAT_NEED_KEY))
        break;
 
       /* Can't validate because we need a key/DS whose name now in keyname.
@@ -1688,9 +1785,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
       if (!packet)
        {
          packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16));
-         payload = &packet[2];
-         new_header = (struct dns_header *)payload;
-         length = (u16 *)packet;
+         new_header = (struct dns_header *)&packet[2];
        }
       
       if (!packet)
@@ -1700,112 +1795,26 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
        }
 
       m = dnssec_generate_query(new_header, ((unsigned char *) new_header) + 65536, keyname, class, 
-                               new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS, server->edns_pktsz);
+                               STAT_ISEQUAL(new_status, STAT_NEED_KEY) ? T_DNSKEY : T_DS, server->edns_pktsz);
       
-      *length = htons(m);
-
-      /* Find server to forward to. This will normally be the 
-        same as for the original query, but may be another if
-        servers for domains are involved. */                 
-      if (search_servers(now, NULL, F_DNSSECOK, keyname, &type, &domain, NULL) != 0)
+      if ((start = dnssec_server(server, daemon->keyname, &first, &last)) == -1 ||
+         (m = tcp_talk(first, last, start, packet, m, have_mark, mark, &server)) == 0)
        {
          new_status = STAT_ABANDONED;
          break;
        }
-       
-      while (1)
-       {
-         int data_sent = 0;
-         
-         if (!firstsendto)
-           firstsendto = server;
-         else
-           {
-             if (!(server = server->next))
-               server = daemon->servers;
-             if (server == firstsendto)
-               {
-                 /* can't find server to accept our query. */
-                 new_status = STAT_ABANDONED;
-                 break;
-               }
-           }
-         
-         if (type != (server->flags & (SERV_TYPE | SERV_DO_DNSSEC)) ||
-             (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, server->domain)) ||
-             (server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
-           continue;
-
-       retry:
-         /* may need to make new connection. */
-         if (server->tcpfd == -1)
-           {
-             if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
-               continue; /* No good, next server */
-             
-#ifdef HAVE_CONNTRACK
-             /* Copy connection mark of incoming query to outgoing connection. */
-             if (have_mark)
-               setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
-#endif 
-             
-             if (!local_bind(server->tcpfd,  &server->source_addr, server->interface, 0, 1))
-               {
-                 close(server->tcpfd);
-                 server->tcpfd = -1;
-                 continue; /* No good, next server */
-               }
-             
-#ifdef MSG_FASTOPEN
-             while(retry_send(sendto(server->tcpfd, packet, m + sizeof(u16),
-                                     MSG_FASTOPEN, &server->addr.sa, sa_len(&server->addr))));
-             
-             if (errno == 0)
-               data_sent = 1;
-#endif
-             
-             if (!data_sent && connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
-               {
-                 close(server->tcpfd);
-                 server->tcpfd = -1;
-                 continue; /* No good, next server */
-               }
-             
-             server->flags &= ~SERV_GOT_TCP;
-           }
-         
-         if ((!data_sent && !read_write(server->tcpfd, packet, m + sizeof(u16), 0)) ||
-             !read_write(server->tcpfd, &c1, 1, 1) ||
-             !read_write(server->tcpfd, &c2, 1, 1) ||
-             !read_write(server->tcpfd, payload, (c1 << 8) | c2, 1))
-           {
-             close(server->tcpfd);
-             server->tcpfd = -1;
-             /* We get data then EOF, reopen connection to same server,
-                else try next. This avoids DoS from a server which accepts
-                connections and then closes them. */
-             if (server->flags & SERV_GOT_TCP)
-               goto retry;
-             else
-               continue;
-           }
 
+      log_save = daemon->log_display_id;
+      daemon->log_display_id = ++daemon->log_id;
+      
+      log_query_mysockaddr(F_NOEXTRA | F_DNSSEC, keyname, &server->addr,
+                          querystr("dnssec-query", STAT_ISEQUAL(new_status, STAT_NEED_KEY) ? T_DNSKEY : T_DS));
+            
+      new_status = tcp_key_recurse(now, new_status, new_header, m, class, name, keyname, server, have_mark, mark, keycount);
 
-         if (server->addr.sa.sa_family == AF_INET) 
-           log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, keyname, (union all_addr *)&(server->addr.in.sin_addr),
-                     querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS));
-         else
-           log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, keyname, (union all_addr *)&(server->addr.in6.sin6_addr),
-                     querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS));
-         
-         server->flags |= SERV_GOT_TCP;
-         
-         m = (c1 << 8) | c2;
-         new_status = tcp_key_recurse(now, new_status, new_header, m, class, name, keyname, server, have_mark, mark, keycount);
-         break;
-       }
+      daemon->log_display_id = log_save;
       
-      if (new_status != STAT_OK)
+      if (!STAT_ISEQUAL(new_status, STAT_OK))
        break;
     }
     
@@ -1825,7 +1834,10 @@ unsigned char *tcp_request(int confd, time_t now,
                           union mysockaddr *local_addr, struct in_addr netmask, int auth_dns)
 {
   size_t size = 0;
-  int norebind = 0;
+  int norebind;
+#ifdef HAVE_CONNTRACK
+  int is_single_query = 0, allowed = 1;
+#endif
 #ifdef HAVE_AUTH
   int local_auth = 0;
 #endif
@@ -1834,14 +1846,14 @@ unsigned char *tcp_request(int confd, time_t now,
   size_t m;
   unsigned short qtype;
   unsigned int gotname;
-  unsigned char c1, c2;
   /* Max TCP packet + slop + size */
   unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16));
   unsigned char *payload = &packet[2];
+  unsigned char c1, c2;
   /* largest field in header is 16-bits, so this is still sufficiently aligned */
   struct dns_header *header = (struct dns_header *)payload;
   u16 *length = (u16 *)packet;
-  struct server *last_server;
+  struct server *serv;
   struct in_addr dst_addr_4;
   union mysockaddr peer_addr;
   socklen_t peer_len = sizeof(union mysockaddr);
@@ -1849,16 +1861,15 @@ unsigned char *tcp_request(int confd, time_t now,
   unsigned char *pheader;
   unsigned int mark = 0;
   int have_mark = 0;
-
-  (void)mark;
-  (void)have_mark;
-
+  int first, last;
+  unsigned int flags = 0;
+    
   if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) == -1)
     return packet;
 
 #ifdef HAVE_CONNTRACK
   /* Get connection mark of incoming query to set on outgoing connections. */
-  if (option_bool(OPT_CONNTRACK))
+  if (option_bool(OPT_CONNTRACK) || option_bool(OPT_CMARK_ALST_EN))
     {
       union all_addr local;
                      
@@ -1903,6 +1914,8 @@ unsigned char *tcp_request(int confd, time_t now,
 
   while (1)
     {
+      int ede = EDE_UNSET;
+
       if (query_count == TCP_MAX_QUERIES ||
          !packet ||
          !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
@@ -1935,12 +1948,12 @@ unsigned char *tcp_request(int confd, time_t now,
 #endif
          char *types = querystr(auth_dns ? "auth" : "query", qtype);
          
-         if (peer_addr.sa.sa_family == AF_INET) 
-           log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 
-                     (union all_addr *)&peer_addr.in.sin_addr, types);
-         else
-           log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 
-                     (union all_addr *)&peer_addr.in6.sin6_addr, types);
+         log_query_mysockaddr(F_QUERY | F_FORWARD, daemon->namebuff,
+                              &peer_addr, types);
+         
+#ifdef HAVE_CONNTRACK
+         is_single_query = 1;
+#endif
          
 #ifdef HAVE_AUTH
          /* find queries for zones we're authoritative for, and answer them directly */
@@ -1955,6 +1968,8 @@ unsigned char *tcp_request(int confd, time_t now,
 #endif
        }
       
+      norebind = domain_no_rebind(daemon->namebuff);
+      
       if (local_addr->sa.sa_family == AF_INET)
        dst_addr_4 = local_addr->in.sin_addr;
       else
@@ -1973,13 +1988,34 @@ unsigned char *tcp_request(int confd, time_t now,
          if (flags & 0x8000)
            do_bit = 1; /* do bit */ 
        }
+      
+#ifdef HAVE_CONNTRACK
+#ifdef HAVE_AUTH
+      if (!auth_dns || local_auth)
+#endif
+       if (option_bool(OPT_CMARK_ALST_EN) && have_mark && ((u32)mark & daemon->allowlist_mask))
+         allowed = is_query_allowed_for_mark((u32)mark, is_single_query ? daemon->namebuff : NULL);
+#endif
+
+      if (0);
+#ifdef HAVE_CONNTRACK
+      else if (!allowed)
+       {
+         u16 swap = htons(EDE_BLOCKED);
 
+         m = answer_disallowed(header, size, (u32)mark, is_single_query ? daemon->namebuff : NULL);
+         
+         if (have_pseudoheader && m != 0)
+           m = add_pseudoheader(header,  m, ((unsigned char *) header) + 65536, daemon->edns_pktsz,
+                                EDNS0_OPTION_EDE, (unsigned char *)&swap, 2, do_bit, 0);
+       }
+#endif
 #ifdef HAVE_AUTH
-      if (auth_dns)
+      else if (auth_dns)
        m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now, &peer_addr, 
                        local_auth, do_bit, have_pseudoheader);
-      else
 #endif
+      else
        {
           int ad_reqd = do_bit;
           /* RFC 6840 5.7 */
@@ -1995,286 +2031,340 @@ unsigned char *tcp_request(int confd, time_t now,
          
          if (m == 0)
            {
-             unsigned int flags = 0;
-             union all_addr *addrp = NULL;
-             int type = SERV_DO_DNSSEC;
-             char *domain = NULL;
-             unsigned char *oph = find_pseudoheader(header, size, NULL, NULL, NULL, NULL);
-
-             size = add_edns0_config(header, size, ((unsigned char *) header) + 65536, &peer_addr, now, &check_subnet, &cacheable);
+             struct server *master;
+             int start;
 
-             if (gotname)
-               flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
-
-#ifdef HAVE_DNSSEC
-             if (option_bool(OPT_DNSSEC_VALID) && (type & SERV_DO_DNSSEC))
+             if (lookup_domain(daemon->namebuff, gotname, &first, &last))
+               flags = is_local_answer(now, first, daemon->namebuff);
+             else
                {
-                 size = add_do_bit(header, size, ((unsigned char *) header) + 65536);
-                 
-                 /* For debugging, set Checking Disabled, otherwise, have the upstream check too,
-                    this allows it to select auth servers when one is returning bad data. */
-                 if (option_bool(OPT_DNSSEC_DEBUG))
-                   header->hb4 |= HB4_CD;
+                 /* No configured servers */
+                 ede = EDE_NOT_READY;
+                 flags = 0;
                }
-#endif
-
-             /* Check if we added a pheader on forwarding - may need to
-                strip it from the reply. */
-             if (!oph && find_pseudoheader(header, size, NULL, NULL, NULL, NULL))
-               added_pheader = 1;
-
-             type &= ~SERV_DO_DNSSEC;
              
-             if (type != 0  || option_bool(OPT_ORDER) || !daemon->last_server)
-               last_server = daemon->servers;
-             else
-               last_server = daemon->last_server;
-             
-             if (!flags && last_server)
+             /* don't forward A or AAAA queries for simple names, except the empty name */
+             if (!flags &&
+                 option_bool(OPT_NODOTS_LOCAL) &&
+                 (gotname & (F_IPV4 | F_IPV6)) &&
+                 !strchr(daemon->namebuff, '.') &&
+                 strlen(daemon->namebuff) != 0)
+               flags = check_for_local_domain(daemon->namebuff, now) ? F_NOERR : F_NXDOMAIN;
+               
+             if (!flags && ede != EDE_NOT_READY)
                {
-                 struct server *firstsendto = NULL;
-                 unsigned char hash[HASH_SIZE];
-                 memcpy(hash, hash_questions(header, (unsigned int)size, daemon->namebuff), HASH_SIZE);
-
-                 /* Loop round available servers until we succeed in connecting to one.
-                    Note that this code subtly ensures that consecutive queries on this connection
-                    which can go to the same server, do so. */
-                 while (1) 
+                 master = daemon->serverarray[first];
+                 
+                 if (option_bool(OPT_ORDER) || master->last_server == -1)
+                   start = first;
+                 else
+                   start = master->last_server;
+                 
+                 size = add_edns0_config(header, size, ((unsigned char *) header) + 65536, &peer_addr, now, &check_subnet, &cacheable);
+                 
+#ifdef HAVE_DNSSEC
+                 if (option_bool(OPT_DNSSEC_VALID) && (master->flags & SERV_DO_DNSSEC))
                    {
-                     int data_sent = 0;
-
-                     if (!firstsendto)
-                       firstsendto = last_server;
-                     else
-                       {
-                         if (!(last_server = last_server->next))
-                           last_server = daemon->servers;
-                         
-                         if (last_server == firstsendto)
-                           break;
-                       }
-                     
-                     /* server for wrong domain */
-                     if (type != (last_server->flags & SERV_TYPE) ||
-                         (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)) ||
-                         (last_server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
-                       continue;
-
-                   retry:
-                     *length = htons(size);
-
-                     if (last_server->tcpfd == -1)
-                       {
-                         if ((last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
-                           continue;
-                         
-#ifdef HAVE_CONNTRACK
-                         /* Copy connection mark of incoming query to outgoing connection. */
-                         if (have_mark)
-                           setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
-#endif                   
+                     size = add_do_bit(header, size, ((unsigned char *) header) + 65536);
                      
-                         if ((!local_bind(last_server->tcpfd,  &last_server->source_addr, last_server->interface, 0, 1)))
-                           {
-                             close(last_server->tcpfd);
-                             last_server->tcpfd = -1;
-                             continue;
-                           }
-                         
-#ifdef MSG_FASTOPEN
-                           while(retry_send(sendto(last_server->tcpfd, packet, size + sizeof(u16),
-                                                   MSG_FASTOPEN, &last_server->addr.sa, sa_len(&last_server->addr))));
-                           
-                           if (errno == 0)
-                             data_sent = 1;
-#endif
-                           
-                           if (!data_sent && connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1)
-                           {
-                             close(last_server->tcpfd);
-                             last_server->tcpfd = -1;
-                             continue;
-                           }
-                         
-                         last_server->flags &= ~SERV_GOT_TCP;
-                       }
+                     /* For debugging, set Checking Disabled, otherwise, have the upstream check too,
+                        this allows it to select auth servers when one is returning bad data. */
+                     if (option_bool(OPT_DNSSEC_DEBUG))
+                       header->hb4 |= HB4_CD;
+                   }
+#endif
+                 
+                 /* Check if we added a pheader on forwarding - may need to
+                    strip it from the reply. */
+                 if (!have_pseudoheader && find_pseudoheader(header, size, NULL, NULL, NULL, NULL))
+                   added_pheader = 1;
+                 
+                 /* Loop round available servers until we succeed in connecting to one. */
+                 if ((m = tcp_talk(first, last, start, packet, size, have_mark, mark, &serv)) == 0)
+                   {
+                     ede = EDE_NETERR;
+                     break;
+                   }
+                 
+                 /* get query name again for logging - may have been overwritten */
+                 if (!(gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
+                   strcpy(daemon->namebuff, "query");
+                 log_query_mysockaddr(F_SERVER | F_FORWARD, daemon->namebuff, &serv->addr, NULL);
+                 
+#ifdef HAVE_DNSSEC
+                 if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (master->flags & SERV_DO_DNSSEC))
+                   {
+                     int keycount = DNSSEC_WORK; /* Limit to number of DNSSEC questions, to catch loops and avoid filling cache. */
+                     int status = tcp_key_recurse(now, STAT_OK, header, m, 0, daemon->namebuff, daemon->keyname, 
+                                                  serv, have_mark, mark, &keycount);
+                     char *result, *domain = "result";
                      
-                     /* get query name again for logging - may have been overwritten */
-                     if (!(gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
-                       strcpy(daemon->namebuff, "query");
+                     union all_addr a;
+                     a.log.ede = ede = errflags_to_ede(status);
                      
-                     if ((!data_sent && !read_write(last_server->tcpfd, packet, size + sizeof(u16), 0)) ||
-                         !read_write(last_server->tcpfd, &c1, 1, 1) ||
-                         !read_write(last_server->tcpfd, &c2, 1, 1) ||
-                         !read_write(last_server->tcpfd, payload, (c1 << 8) | c2, 1))
+                     if (STAT_ISEQUAL(status, STAT_ABANDONED))
                        {
-                         close(last_server->tcpfd);
-                         last_server->tcpfd = -1;
-                         /* We get data then EOF, reopen connection to same server,
-                            else try next. This avoids DoS from a server which accepts
-                            connections and then closes them. */
-                         if (last_server->flags & SERV_GOT_TCP)
-                           goto retry;
-                         else
-                           continue;
+                         result = "ABANDONED";
+                         status = STAT_BOGUS;
                        }
-                     
-                     last_server->flags |= SERV_GOT_TCP;
-
-                     m = (c1 << 8) | c2;
-                     
-                     if (last_server->addr.sa.sa_family == AF_INET)
-                       log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 
-                                 (union all_addr *)&last_server->addr.in.sin_addr, NULL); 
                      else
-                       log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 
-                                 (union all_addr *)&last_server->addr.in6.sin6_addr, NULL);
-
-#ifdef HAVE_DNSSEC
-                     if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (last_server->flags & SERV_DO_DNSSEC))
+                       result = (STAT_ISEQUAL(status, STAT_SECURE) ? "SECURE" : (STAT_ISEQUAL(status, STAT_INSECURE) ? "INSECURE" : "BOGUS"));
+                     
+                     if (STAT_ISEQUAL(status, STAT_SECURE))
+                       cache_secure = 1;
+                     else if (STAT_ISEQUAL(status, STAT_BOGUS))
                        {
-                         int keycount = DNSSEC_WORK; /* Limit to number of DNSSEC questions, to catch loops and avoid filling cache. */
-                         int status = tcp_key_recurse(now, STAT_OK, header, m, 0, daemon->namebuff, daemon->keyname, 
-                                                      last_server, have_mark, mark, &keycount);
-                         char *result, *domain = "result";
-                         
-                         if (status == STAT_ABANDONED)
-                           {
-                             result = "ABANDONED";
-                             status = STAT_BOGUS;
-                           }
-                         else
-                           result = (status == STAT_SECURE ? "SECURE" : (status == STAT_INSECURE ? "INSECURE" : "BOGUS"));
+                         no_cache_dnssec = 1;
+                         bogusanswer = 1;
                          
-                         if (status == STAT_BOGUS && extract_request(header, m, daemon->namebuff, NULL))
+                         if (extract_request(header, m, daemon->namebuff, NULL))
                            domain = daemon->namebuff;
-
-                         log_query(F_SECSTAT, domain, NULL, result);
-                         
-                         if (status == STAT_BOGUS)
-                           {
-                             no_cache_dnssec = 1;
-                             bogusanswer = 1;
-                           }
-
-                         if (status == STAT_SECURE)
-                           cache_secure = 1;
-                       }
-#endif
-
-                     /* restore CD bit to the value in the query */
-                     if (checking_disabled)
-                       header->hb4 |= HB4_CD;
-                     else
-                       header->hb4 &= ~HB4_CD;
-                     
-                     /* There's no point in updating the cache, since this process will exit and
-                        lose the information after a few queries. We make this call for the alias and 
-                        bogus-nxdomain side-effects. */
-                     /* If the crc of the question section doesn't match the crc we sent, then
-                        someone might be attempting to insert bogus values into the cache by 
-                        sending replies containing questions and bogus answers. */
-                     if (memcmp(hash, hash_questions(header, (unsigned int)m, daemon->namebuff), HASH_SIZE) != 0)
-                       { 
-                         m = 0;
-                         break;
                        }
-
-                     /* Never cache answers which are contingent on the source or MAC address EDSN0 option,
-                        since the cache is ignorant of such things. */
-                     if (!cacheable)
-                       no_cache_dnssec = 1;
-                     
-                     m = process_reply(header, now, last_server, (unsigned int)m, 
-                                       option_bool(OPT_NO_REBIND) && !norebind, no_cache_dnssec, cache_secure, bogusanswer,
-                                       ad_reqd, do_bit, added_pheader, check_subnet, &peer_addr); 
                      
-                     break;
+                     log_query(F_SECSTAT, domain, &a, result);
                    }
-               }
-       
-             /* In case of local answer or no connections made. */
-             if (m == 0)
-               {
-                 m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
-                 if (have_pseudoheader)
-                   m = add_pseudoheader(header, m, ((unsigned char *) header) + 65536, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
+#endif
+                 
+                 /* restore CD bit to the value in the query */
+                 if (checking_disabled)
+                   header->hb4 |= HB4_CD;
+                 else
+                   header->hb4 &= ~HB4_CD;
+                 
+                 /* Never cache answers which are contingent on the source or MAC address EDSN0 option,
+                    since the cache is ignorant of such things. */
+                 if (!cacheable)
+                   no_cache_dnssec = 1;
+                 
+                 m = process_reply(header, now, serv, (unsigned int)m, 
+                                   option_bool(OPT_NO_REBIND) && !norebind, no_cache_dnssec, cache_secure, bogusanswer,
+                                   ad_reqd, do_bit, added_pheader, check_subnet, &peer_addr, ((unsigned char *)header) + 65536, ede); 
                }
            }
        }
+       
+      /* In case of local answer or no connections made. */
+      if (m == 0)
+       {
+         if (!(m = make_local_answer(flags, gotname, size, header, daemon->namebuff,
+                                     ((char *) header) + 65536, first, last, ede)))
+           break;
          
+         if (have_pseudoheader)
+           {
+             u16 swap = htons((u16)ede);
+
+              if (ede != EDE_UNSET)
+                m = add_pseudoheader(header, m, ((unsigned char *) header) + 65536, daemon->edns_pktsz, EDNS0_OPTION_EDE, (unsigned char *)&swap, 2, do_bit, 0);
+              else
+                m = add_pseudoheader(header, m, ((unsigned char *) header) + 65536, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
+           }
+       }
+      
       check_log_writer(1);
       
       *length = htons(m);
-           
-      if (m == 0 || !read_write(confd, packet, m + sizeof(u16), 0))
-       return packet;
+      
+#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
+#ifdef HAVE_AUTH
+      if (!auth_dns || local_auth)
+#endif
+       if (option_bool(OPT_CMARK_ALST_EN) && have_mark && ((u32)mark & daemon->allowlist_mask))
+         report_addresses(header, m, mark);
+#endif
+      if (!read_write(confd, packet, m + sizeof(u16), 0))
+       break;
     }
+  
+  return packet;
 }
 
-static struct frec *allocate_frec(time_t now)
+/* return a UDP socket bound to a random port, have to cope with straying into
+   occupied port nos and reserved ones. */
+static int random_sock(struct server *s)
 {
-  struct frec *f;
-  
-  if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
+  int fd;
+
+  if ((fd = socket(s->source_addr.sa.sa_family, SOCK_DGRAM, 0)) != -1)
     {
-      f->next = daemon->frec_list;
-      f->time = now;
-      f->sentto = NULL;
-      f->rfd4 = NULL;
-      f->flags = 0;
-      f->rfd6 = NULL;
-#ifdef HAVE_DNSSEC
-      f->dependent = NULL;
-      f->blocking_query = NULL;
-      f->stash = NULL;
-#endif
-      daemon->frec_list = f;
+      if (local_bind(fd, &s->source_addr, s->interface, s->ifindex, 0))
+       return fd;
+
+      if (s->interface[0] == 0)
+       (void)prettyprint_addr(&s->source_addr, daemon->namebuff);
+      else
+       strcpy(daemon->namebuff, s->interface);
+
+      my_syslog(LOG_ERR, _("failed to bind server socket to %s: %s"),
+               daemon->namebuff, strerror(errno));
+      close(fd);
     }
+  
+  return -1;
+}
 
-  return f;
+/* compare source addresses and interface, serv2 can be null. */
+static int server_isequal(const struct server *serv1,
+                        const struct server *serv2)
+{
+  return (serv2 &&
+    serv2->ifindex == serv1->ifindex &&
+    sockaddr_isequal(&serv2->source_addr, &serv1->source_addr) &&
+    strncmp(serv2->interface, serv1->interface, IF_NAMESIZE) == 0);
 }
 
-struct randfd *allocate_rfd(int family)
+/* fdlp points to chain of randomfds already in use by transaction.
+   If there's already a suitable one, return it, else allocate a 
+   new one and add it to the list. 
+
+   Not leaking any resources in the face of allocation failures
+   is rather convoluted here.
+   
+   Note that rfd->serv may be NULL, when a server goes away.
+*/
+int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
 {
   static int finger = 0;
-  int i;
-
+  int i, j = 0;
+  struct randfd_list *rfl;
+  struct randfd *rfd = NULL;
+  int fd = 0;
+  
+  /* If server has a pre-allocated fd, use that. */
+  if (serv->sfd)
+    return serv->sfd->fd;
+  
+  /* existing suitable random port socket linked to this transaction? */
+  for (rfl = *fdlp; rfl; rfl = rfl->next)
+    if (server_isequal(serv, rfl->rfd->serv))
+      return rfl->rfd->fd;
+
+  /* No. need new link. */
+  if ((rfl = daemon->rfl_spare))
+    daemon->rfl_spare = rfl->next;
+  else if (!(rfl = whine_malloc(sizeof(struct randfd_list))))
+    return -1;
+   
   /* limit the number of sockets we have open to avoid starvation of 
      (eg) TFTP. Once we have a reasonable number, randomness should be OK */
-
-  for (i = 0; i < RANDOM_SOCKS; i++)
+  for (i = 0; i < daemon->numrrand; i++)
     if (daemon->randomsocks[i].refcount == 0)
       {
-       if ((daemon->randomsocks[i].fd = random_sock(family)) == -1)
-         break;
-      
-       daemon->randomsocks[i].refcount = 1;
-       daemon->randomsocks[i].family = family;
-       return &daemon->randomsocks[i];
+       if ((fd = random_sock(serv)) != -1)
+         {
+           rfd = &daemon->randomsocks[i];
+           rfd->serv = serv;
+           rfd->fd = fd;
+           rfd->refcount = 1;
+         }
+       break;
       }
-
+  
   /* No free ones or cannot get new socket, grab an existing one */
-  for (i = 0; i < RANDOM_SOCKS; i++)
+  if (!rfd)
+    for (j = 0; j < daemon->numrrand; j++)
+      {
+       i = (j + finger) % daemon->numrrand;
+       if (daemon->randomsocks[i].refcount != 0 &&
+           server_isequal(serv, daemon->randomsocks[i].serv) &&
+           daemon->randomsocks[i].refcount != 0xfffe)
+         {
+           finger = i + 1;
+           rfd = &daemon->randomsocks[i];
+           rfd->refcount++;
+           break;
+         }
+      }
+
+  if (j == daemon->numrrand)
     {
-      int j = (i+finger) % RANDOM_SOCKS;
-      if (daemon->randomsocks[j].refcount != 0 &&
-         daemon->randomsocks[j].family == family && 
-         daemon->randomsocks[j].refcount != 0xffff)
+      struct randfd_list *rfl_poll;
+
+      /* there are no free slots, and non with the same parameters we can piggy-back on. 
+        We're going to have to allocate a new temporary record, distinguished by
+        refcount == 0xffff. This will exist in the frec randfd list, never be shared,
+        and be freed when no longer in use. It will also be held on 
+        the daemon->rfl_poll list so the poll system can find it. */
+
+      if ((rfl_poll = daemon->rfl_spare))
+       daemon->rfl_spare = rfl_poll->next;
+      else
+       rfl_poll = whine_malloc(sizeof(struct randfd_list));
+      
+      if (!rfl_poll ||
+         !(rfd = whine_malloc(sizeof(struct randfd))) ||
+         (fd = random_sock(serv)) == -1)
        {
-         finger = j;
-         daemon->randomsocks[j].refcount++;
-         return &daemon->randomsocks[j];
+         
+         /* Don't leak anything we may already have */
+         rfl->next = daemon->rfl_spare;
+         daemon->rfl_spare = rfl;
+
+         if (rfl_poll)
+           {
+             rfl_poll->next = daemon->rfl_spare;
+             daemon->rfl_spare = rfl_poll;
+           }
+         
+         if (rfd)
+           free(rfd);
+         
+         return -1; /* doom */
        }
-    }
 
-  return NULL; /* doom */
+      /* Note rfd->serv not set here, since it's not reused */
+      rfd->fd = fd;
+      rfd->refcount = 0xffff; /* marker for temp record */
+
+      rfl_poll->rfd = rfd;
+      rfl_poll->next = daemon->rfl_poll;
+      daemon->rfl_poll = rfl_poll;
+    }
+  
+  rfl->rfd = rfd;
+  rfl->next = *fdlp;
+  *fdlp = rfl;
+  
+  return rfl->rfd->fd;
 }
 
-void free_rfd(struct randfd *rfd)
+void free_rfds(struct randfd_list **fdlp)
 {
-  if (rfd && --(rfd->refcount) == 0)
-    close(rfd->fd);
+  struct randfd_list *tmp, *rfl, *poll, *next, **up;
+  
+  for (rfl = *fdlp; rfl; rfl = tmp)
+    {
+      if (rfl->rfd->refcount == 0xffff || --(rfl->rfd->refcount) == 0)
+       close(rfl->rfd->fd);
+
+      /* temporary overflow record */
+      if (rfl->rfd->refcount == 0xffff)
+       {
+         free(rfl->rfd);
+         
+         /* go through the link of all these by steam to delete.
+            This list is expected to be almost always empty. */
+         for (poll = daemon->rfl_poll, up = &daemon->rfl_poll; poll; poll = next)
+           {
+             next = poll->next;
+             
+             if (poll->rfd == rfl->rfd)
+               {
+                 *up = poll->next;
+                 poll->next = daemon->rfl_spare;
+                 daemon->rfl_spare = poll;
+               }
+             else
+               up = &poll->next;
+           }
+       }
+
+      tmp = rfl->next;
+      rfl->next = daemon->rfl_spare;
+      daemon->rfl_spare = rfl;
+    }
+
+  *fdlp = NULL;
 }
 
 static void free_frec(struct frec *f)
@@ -2290,12 +2380,9 @@ static void free_frec(struct frec *f)
     }
     
   f->frec_src.next = NULL;    
-  free_rfd(f->rfd4);
-  f->rfd4 = NULL;
+  free_rfds(&f->rfds);
   f->sentto = NULL;
   f->flags = 0;
-  free_rfd(f->rfd6);
-  f->rfd6 = NULL;
 
 #ifdef HAVE_DNSSEC
   if (f->stash)
@@ -2306,160 +2393,150 @@ static void free_frec(struct frec *f)
 
   /* Anything we're waiting on is pointless now, too */
   if (f->blocking_query)
-    free_frec(f->blocking_query);
+    {
+      struct frec *n, **up;
+
+      /* unlink outselves from the blocking query's dependents list. */
+      for (n = f->blocking_query->dependent, up = &f->blocking_query->dependent; n; n = n->next_dependent)
+       if (n == f)
+         {
+           *up = n->next_dependent;
+           break;
+         }
+       else
+         up = &n->next_dependent;
+
+      /* If we were the only/last dependent, free the blocking query too. */
+      if (!f->blocking_query->dependent)
+       free_frec(f->blocking_query);
+    }
+  
   f->blocking_query = NULL;
   f->dependent = NULL;
+  f->next_dependent = NULL;
 #endif
 }
 
 
 
-/* if wait==NULL return a free or older than TIMEOUT record.
-   else return *wait zero if one available, or *wait is delay to
-   when the oldest in-use record will expire. Impose an absolute
+/* Impose an absolute
    limit of 4*TIMEOUT before we wipe things (for random sockets).
-   If force is non-NULL, always return a result, even if we have
-   to allocate above the limit, and never free the record pointed
-   to by the force argument. */
-struct frec *get_new_frec(time_t now, int *wait, struct frec *force)
+   If force is set, always return a result, even if we have
+   to allocate above the limit, and don'y free any records.
+   This is set when allocating for DNSSEC to avoid cutting off
+   the branch we are sitting on. */
+static struct frec *get_new_frec(time_t now, struct server *master, int force)
 {
   struct frec *f, *oldest, *target;
   int count;
   
-  if (wait)
-    *wait = 0;
-
-  for (f = daemon->frec_list, oldest = NULL, target =  NULL, count = 0; f; f = f->next, count++)
-    if (!f->sentto)
-      target = f;
-    else 
-      {
+  /* look for free records, garbage collect old records and count number in use by our server-group. */
+  for (f = daemon->frec_list, oldest = NULL, target =  NULL, count = 0; f; f = f->next)
+    {
+      if (!f->sentto)
+       target = f;
+      else
+       {
 #ifdef HAVE_DNSSEC
-           /* Don't free DNSSEC sub-queries here, as we may end up with
-              dangling references to them. They'll go when their "real" query 
-              is freed. */
-           if (!f->dependent && f != force)
+         /* Don't free DNSSEC sub-queries here, as we may end up with
+            dangling references to them. They'll go when their "real" query 
+            is freed. */
+         if (!f->dependent && !force)
 #endif
-             {
-               if (difftime(now, f->time) >= 4*TIMEOUT)
-                 {
-                   free_frec(f);
-                   target = f;
-                 }
-            
-           
-               if (!oldest || difftime(f->time, oldest->time) <= 0)
-                 oldest = f;
-             }
-      }
+           {
+             if (difftime(now, f->time) >= 4*TIMEOUT)
+               {
+                 free_frec(f);
+                 target = f;
+               }
+             else if (!oldest || difftime(f->time, oldest->time) <= 0)
+               oldest = f;
+           }
+       }
+      
+      if (f->sentto && ((int)difftime(now, f->time)) < TIMEOUT && server_samegroup(f->sentto, master))
+       count++;
+    }
 
-  if (target)
+  if (!force && count >= daemon->ftabsize)
     {
-      target->time = now;
-      return target;
+      query_full(now, master->domain);
+      return NULL;
     }
   
-  /* can't find empty one, use oldest if there is one
-     and it's older than timeout */
-  if (!force && oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
+  if (!target && oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
     { 
-      /* keep stuff for twice timeout if we can by allocating a new
-        record instead */
-      if (difftime(now, oldest->time) < 2*TIMEOUT && 
-         count <= daemon->ftabsize &&
-         (f = allocate_frec(now)))
-       return f;
-
-      if (!wait)
-       {
-         free_frec(oldest);
-         oldest->time = now;
-       }
-      return oldest;
+      /* can't find empty one, use oldest if there is one and it's older than timeout */
+      free_frec(oldest);
+      target = oldest;
     }
   
-  /* none available, calculate time 'till oldest record expires */
-  if (!force && count > daemon->ftabsize)
+  if (!target && (target = (struct frec *)whine_malloc(sizeof(struct frec))))
     {
-      static time_t last_log = 0;
-      
-      if (oldest && wait)
-       *wait = oldest->time + (time_t)TIMEOUT - now;
-      
-      if ((int)difftime(now, last_log) > 5)
-       {
-         last_log = now;
-         my_syslog(LOG_WARNING, _("Maximum number of concurrent DNS queries reached (max: %d)"), daemon->ftabsize);
-       }
-
-      return NULL;
+      target->next = daemon->frec_list;
+      daemon->frec_list = target;
     }
-  
-  if (!(f = allocate_frec(now)) && wait)
-    /* wait one second on malloc failure */
-    *wait = 1;
 
-  return f; /* OK if malloc fails and this is NULL */
+  if (target)
+    target->time = now;
+
+  return target;
 }
 
-static struct frec *lookup_frec(unsigned short id, int fd, int family, void *hash)
+static void query_full(time_t now, char *domain)
 {
-  struct frec *f;
+  static time_t last_log = 0;
+  
+  if ((int)difftime(now, last_log) > 5)
+    {
+      last_log = now;
+      if (!domain || strlen(domain) == 0)
+       my_syslog(LOG_WARNING, _("Maximum number of concurrent DNS queries reached (max: %d)"), daemon->ftabsize);
+      else
+       my_syslog(LOG_WARNING, _("Maximum number of concurrent DNS queries to %s reached (max: %d)"), domain, daemon->ftabsize);
+    }
+}
 
+
+static struct frec *lookup_frec(unsigned short id, int fd, void *hash, int *firstp, int *lastp)
+{
+  struct frec *f;
+  struct server *s;
+  int first, last;
+  struct randfd_list *fdl;
+  
   for(f = daemon->frec_list; f; f = f->next)
     if (f->sentto && f->new_id == id && 
        (memcmp(hash, f->hash, HASH_SIZE) == 0))
       {
-       /* sent from random port */
-       if (family == AF_INET && f->rfd4 && f->rfd4->fd == fd)
-         return f;
-
-       if (family == AF_INET6 && f->rfd6 && f->rfd6->fd == fd)
-         return f;
+       filter_servers(f->sentto->arrayposn, F_SERVER, firstp, lastp);
 
-       /* sent to upstream from bound socket. */
-       if (f->sentto->sfd && f->sentto->sfd->fd == fd)
+       /* sent from random port */
+       for (fdl = f->rfds; fdl; fdl = fdl->next)
+         if (fdl->rfd->fd == fd)
          return f;
+       
+       /* Sent to upstream from socket associated with a server. 
+          Note we have to iterate over all the possible servers, since they may
+          have different bound sockets. */
+       for (first = *firstp, last = *lastp; first != last; first++)
+         {
+           s = daemon->serverarray[first];
+           if (s->sfd && s->sfd->fd == fd)
+             return f;
+         }
       }
-      
-  return NULL;
-}
-
-static struct frec *lookup_frec_by_sender(unsigned short id,
-                                         union mysockaddr *addr,
-                                         void *hash)
-{
-  struct frec *f;
-  struct frec_src *src;
-
-  for (f = daemon->frec_list; f; f = f->next)
-    if (f->sentto &&
-       !(f->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) &&
-       memcmp(hash, f->hash, HASH_SIZE) == 0)
-      for (src = &f->frec_src; src; src = src->next)
-       if (src->orig_id == id && 
-           sockaddr_isequal(&src->source, addr))
-         return f;
   
   return NULL;
 }
 
-static struct frec *lookup_frec_by_query(void *hash, unsigned int flags)
+static struct frec *lookup_frec_by_query(void *hash, unsigned int flags, unsigned int flagmask)
 {
   struct frec *f;
 
-  /* FREC_DNSKEY and FREC_DS_QUERY are never set in flags, so the test below 
-     ensures that no frec created for internal DNSSEC query can be returned here.
-     
-     Similarly FREC_NO_CACHE is never set in flags, so a query which is
-     contigent on a particular source address EDNS0 option will never be matched. */
-
-#define FLAGMASK (FREC_CHECKING_DISABLED | FREC_AD_QUESTION | FREC_DO_QUESTION \
-                 | FREC_HAS_PHEADER | FREC_DNSKEY_QUERY | FREC_DS_QUERY | FREC_NO_CACHE)
-  
   for(f = daemon->frec_list; f; f = f->next)
     if (f->sentto &&
-       (f->flags & FLAGMASK) == flags &&
+       (f->flags & flagmask) == flags &&
        memcmp(hash, f->hash, HASH_SIZE) == 0)
       return f;
   
@@ -2470,34 +2547,26 @@ static struct frec *lookup_frec_by_query(void *hash, unsigned int flags)
 void resend_query()
 {
   if (daemon->srv_save)
-    {
-      int fd;
-      
-      if (daemon->srv_save->sfd)
-       fd = daemon->srv_save->sfd->fd;
-      else if (daemon->rfd_save && daemon->rfd_save->refcount != 0)
-       fd = daemon->rfd_save->fd;
-      else
-       return;
-      
-      while(retry_send(sendto(fd, daemon->packet, daemon->packet_len, 0,
-                             &daemon->srv_save->addr.sa, 
-                             sa_len(&daemon->srv_save->addr)))); 
-    }
+    server_send(daemon->srv_save, daemon->fd_save,
+               daemon->packet, daemon->packet_len, 0);
 }
 
 /* A server record is going away, remove references to it */
 void server_gone(struct server *server)
 {
   struct frec *f;
+  int i;
   
   for (f = daemon->frec_list; f; f = f->next)
     if (f->sentto && f->sentto == server)
       free_frec(f);
-  
-  if (daemon->last_server == server)
-    daemon->last_server = NULL;
 
+  /* If any random socket refers to this server, NULL the reference.
+     No more references to the socket will be created in the future. */
+  for (i = 0; i < daemon->numrrand; i++)
+    if (daemon->randomsocks[i].refcount != 0 && daemon->randomsocks[i].serv == server)
+      daemon->randomsocks[i].serv = NULL;
+  
   if (daemon->srv_save == server)
     daemon->srv_save = NULL;
 }
@@ -2521,8 +2590,3 @@ static unsigned short get_id(void)
        return ret;
     }
 }
-
-
-
-
-
similarity index 88%
rename from src/hash_questions.c
rename to src/hash-questions.c
index 51d88c2..f41023b 100644 (file)
 
 #include "dnsmasq.h"
 
-#if defined(HAVE_DNSSEC) || defined(HAVE_NETTLEHASH)
+#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH)
+
+static const struct nettle_hash *hash;
+static void *ctx;
+static unsigned char *digest;
+
+void hash_questions_init(void)
+{
+  if (!(hash = hash_find("sha256")))
+    die(_("Failed to create SHA-256 hash object"), NULL, EC_MISC);
+
+  ctx = safe_malloc(hash->context_size);
+  digest = safe_malloc(hash->digest_size);
+}
+
 unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name)
 {
   int q;
   unsigned char *p = (unsigned char *)(header+1);
-  const struct nettle_hash *hash;
-  void *ctx;
-  unsigned char *digest;
-  
-  if (!(hash = hash_find("sha256")) || !hash_init(hash, &ctx, &digest))
-    {
-      /* don't think this can ever happen. */
-      static unsigned char dummy[HASH_SIZE];
-      static int warned = 0;
-
-      if (!warned)
-       my_syslog(LOG_ERR, _("Failed to create SHA-256 hash object"));
-      warned = 1;
-     
-      return dummy;
-    }
-  
+
+  hash->init(ctx);
+
   for (q = ntohs(header->qdcount); q != 0; q--) 
     {
       char *cp, c;
@@ -74,11 +74,11 @@ unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name
   return digest;
 }
 
-#else /* HAVE_DNSSEC */
+#else /* HAVE_DNSSEC  || HAVE_CRYPTOHASH */
 
-#define SHA256_BLOCK_SIZE 32            // SHA256 outputs a 32 byte digest
-typedef unsigned char BYTE;             // 8-bit byte
-typedef unsigned int  WORD;             // 32-bit word, change to "long" for 16-bit machines
+#define SHA256_BLOCK_SIZE 32            /* SHA256 outputs a 32 byte digest */
+typedef unsigned char BYTE;             /* 8-bit byte */
+typedef unsigned int  WORD;             /* 32-bit word, change to "long" for 16-bit machines */
 
 typedef struct {
   BYTE data[64];
@@ -91,6 +91,9 @@ static void sha256_init(SHA256_CTX *ctx);
 static void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len);
 static void sha256_final(SHA256_CTX *ctx, BYTE hash[]);
 
+void hash_questions_init(void)
+{
+}
 
 unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name)
 {
@@ -235,7 +238,7 @@ static void sha256_final(SHA256_CTX *ctx, BYTE hash[])
   
   i = ctx->datalen;
 
-  // Pad whatever data is left in the buffer.
+  /* Pad whatever data is left in the buffer. */
   if (ctx->datalen < 56)
     {
       ctx->data[i++] = 0x80;
@@ -251,7 +254,7 @@ static void sha256_final(SHA256_CTX *ctx, BYTE hash[])
       memset(ctx->data, 0, 56);
     }
   
-  // Append to the padding the total message's length in bits and transform.
+  /* Append to the padding the total message's length in bits and transform. */
   ctx->bitlen += ctx->datalen * 8;
   ctx->data[63] = ctx->bitlen;
   ctx->data[62] = ctx->bitlen >> 8;
@@ -263,8 +266,8 @@ static void sha256_final(SHA256_CTX *ctx, BYTE hash[])
   ctx->data[56] = ctx->bitlen >> 56;
   sha256_transform(ctx, ctx->data);
   
-  // Since this implementation uses little endian byte ordering and SHA uses big endian,
-  // reverse all the bytes when copying the final state to the output hash.
+  /* Since this implementation uses little endian byte ordering and SHA uses big endian,
+     reverse all the bytes when copying the final state to the output hash. */
   for (i = 0; i < 4; ++i)
     {
       hash[i]      = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
index 7072cf4..02340a0 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -235,7 +235,6 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
        }
        else 
        continue;
-
        
       /* stringify MAC into dhcp_buff */
       p = daemon->dhcp_buff;
@@ -433,7 +432,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
                buf = grab_extradata_lua(buf, end, "relay_address");
              else if (data.giaddr.s_addr != 0)
                {
-                 lua_pushstring(lua, inet_ntoa(data.giaddr));
+                 inet_ntop(AF_INET, &data.giaddr, daemon->addrbuff, ADDRSTRLEN);
+                 lua_pushstring(lua, daemon->addrbuff);
                  lua_setfield(lua, -2, "relay_address");
                }
              
@@ -611,8 +611,13 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
 
          if (is6)
            buf = grab_extradata(buf, end, "DNSMASQ_RELAY_ADDRESS", &err);
-         else 
-           my_setenv("DNSMASQ_RELAY_ADDRESS", data.giaddr.s_addr != 0 ? inet_ntoa(data.giaddr) : NULL, &err); 
+         else
+           {
+             const char *giaddr = NULL;
+             if (data.giaddr.s_addr != 0)
+                 giaddr = inet_ntop(AF_INET, &data.giaddr, daemon->addrbuff, ADDRSTRLEN);
+             my_setenv("DNSMASQ_RELAY_ADDRESS", giaddr, &err);
+           }
          
          for (i = 0; buf; i++)
            {
@@ -882,7 +887,4 @@ void helper_write(void)
     }
 }
 
-#endif
-
-
-
+#endif /* HAVE_SCRIPT */
index d5804cb..5776feb 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
  
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -295,4 +295,3 @@ int inotify_check(time_t now)
 }
 
 #endif  /* INOTIFY */
-  
index 352b330..6388c7d 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -31,4 +31,3 @@
          && ((__const uint32_t *) (a))[1] == 0                                \
          && ((__const uint32_t *) (a))[2] == 0                                \
          && ((__const uint32_t *) (a))[3] == 0)
-
index 23e6fe0..1a9f1c6 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -378,7 +378,7 @@ void lease_update_file(time_t now)
       if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)
        next_event = LEASE_RETRY + now;
       
-      my_syslog(MS_DHCP | LOG_ERR, _("failed to write %s: %s (retry in %us)"), 
+      my_syslog(MS_DHCP | LOG_ERR, _("failed to write %s: %s (retry in %u s)"), 
                daemon->lease_file, strerror(err),
                (unsigned int)difftime(next_event, now));
     }
@@ -1021,6 +1021,7 @@ void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, ch
            }
        
          kill_name(lease_tmp);
+         lease_tmp->flags |= LEASE_CHANGED; /* run script on change */
          break;
        }
     }
@@ -1201,8 +1202,4 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned
 }
 #endif
 
-#endif
-         
-
-      
-
+#endif /* HAVE_DHCP */
index dbd6bd4..1ec3447 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -273,7 +273,7 @@ static void log_write(void)
 /* priority is one of LOG_DEBUG, LOG_INFO, LOG_NOTICE, etc. See sys/syslog.h.
    OR'd to priority can be MS_TFTP, MS_DHCP, ... to be able to do log separation between
    DNS, DHCP and TFTP services.
-*/
+   If OR'd with MS_DEBUG, the messages are suppressed unless --log-debug is set. */
 void my_syslog(int priority, const char *format, ...)
 {
   va_list ap;
@@ -290,7 +290,13 @@ void my_syslog(int priority, const char *format, ...)
     func = "-dhcp";
   else if ((LOG_FACMASK & priority) == MS_SCRIPT)
     func = "-script";
-           
+  else if ((LOG_FACMASK & priority) == MS_DEBUG)
+    {
+      if (!option_bool(OPT_LOG_DEBUG))
+       return;
+      func = "-debug";
+    }
+  
 #ifdef LOG_PRI
   priority = LOG_PRI(priority);
 #else
index 78e1238..01f0c28 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@ static ssize_t loop_make_probe(u32 uid);
 void loop_send_probes()
 {
    struct server *serv;
+   struct randfd_list *rfds = NULL;
    
    if (!option_bool(OPT_LOOP_DETECT))
      return;
@@ -29,34 +30,29 @@ void loop_send_probes()
    /* Loop through all upstream servers not for particular domains, and send a query to that server which is
       identifiable, via the uid. If we see that query back again, then the server is looping, and we should not use it. */
    for (serv = daemon->servers; serv; serv = serv->next)
-     if (!(serv->flags & 
-          (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_LOOP)))
+     if (strlen(serv->domain) == 0 &&
+        !(serv->flags & (SERV_FOR_NODOTS)))
        {
         ssize_t len = loop_make_probe(serv->uid);
         int fd;
-        struct randfd *rfd = NULL;
         
-        if (serv->sfd)
-          fd = serv->sfd->fd;
-        else 
-          {
-            if (!(rfd = allocate_rfd(serv->addr.sa.sa_family)))
-              continue;
-            fd = rfd->fd;
-          }
+        serv->flags &= ~SERV_LOOP;
 
+        if ((fd = allocate_rfd(&rfds, serv)) == -1)
+          continue;
+        
         while (retry_send(sendto(fd, daemon->packet, len, 0, 
                                  &serv->addr.sa, sa_len(&serv->addr))));
-        
-        free_rfd(rfd);
        }
+
+   free_rfds(&rfds);
 }
   
 static ssize_t loop_make_probe(u32 uid)
 {
   struct dns_header *header = (struct dns_header *)daemon->packet;
   unsigned char *p = (unsigned char *)(header+1);
-
+  
   /* packet buffer overwritten */
   daemon->srv_save = NULL;
   
@@ -102,15 +98,15 @@ int detect_loop(char *query, int type)
   uid = strtol(query, NULL, 16);
 
   for (serv = daemon->servers; serv; serv = serv->next)
-     if (!(serv->flags & 
-          (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_LOOP)) &&
-        uid == serv->uid)
-       {
-        serv->flags |= SERV_LOOP;
-        check_servers(); /* log new state */
-        return 1;
-       }
-
+    if (strlen(serv->domain) == 0 &&
+       !(serv->flags & SERV_LOOP) &&
+       uid == serv->uid)
+      {
+       serv->flags |= SERV_LOOP;
+       check_servers(1); /* log new state - don't send more probes. */
+       return 1;
+      }
+  
   return 0;
 }
 
index 79f20b0..fac5b00 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
index ccc92a8..cecf8c8 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
index 8e8431f..7840ef9 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #ifndef NDA_RTA
 #  define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) 
-#endif 
+#endif
+
+/* Used to request refresh of addresses or routes just once,
+ * when multiple changes might be announced. */
+enum async_states {
+  STATE_NEWADDR = (1 << 0),
+  STATE_NEWROUTE = (1 << 1),
+};
 
 
 static struct iovec iov;
 static u32 netlink_pid;
 
-static void nl_async(struct nlmsghdr *h);
+static unsigned nl_async(struct nlmsghdr *h, unsigned state);
+static void nl_multicast_state(unsigned state);
 
 char *netlink_init(void)
 {
   struct sockaddr_nl addr;
   socklen_t slen = sizeof(addr);
-  int opt = 1;
 
   addr.nl_family = AF_NETLINK;
   addr.nl_pad = 0;
@@ -92,14 +99,10 @@ char *netlink_init(void)
   iov.iov_len = 100;
   iov.iov_base = safe_malloc(iov.iov_len);
   
-  if (daemon->kernel_version >= KERNEL_VERSION(2,6,30) &&
-      setsockopt(daemon->netlinkfd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, sizeof(opt)) == -1)
-    return _("warning: failed to set NETLINK_NO_ENOBUFS on netlink socket");
-  
   return NULL;
 }
 
-static ssize_t netlink_recv(void)
+static ssize_t netlink_recv(int flags)
 {
   struct msghdr msg;
   struct sockaddr_nl nladdr;
@@ -115,7 +118,8 @@ static ssize_t netlink_recv(void)
       msg.msg_iovlen = 1;
       msg.msg_flags = 0;
       
-      while ((rc = recvmsg(daemon->netlinkfd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR);
+      while ((rc = recvmsg(daemon->netlinkfd, &msg, flags | MSG_PEEK | MSG_TRUNC)) == -1 &&
+            errno == EINTR);
       
       /* make buffer big enough */
       if (rc != -1 && (msg.msg_flags & MSG_TRUNC))
@@ -132,7 +136,7 @@ static ssize_t netlink_recv(void)
 
       /* read it for real */
       msg.msg_flags = 0;
-      while ((rc = recvmsg(daemon->netlinkfd, &msg, 0)) == -1 && errno == EINTR);
+      while ((rc = recvmsg(daemon->netlinkfd, &msg, flags)) == -1 && errno == EINTR);
       
       /* Make sure this is from the kernel */
       if (rc == -1 || nladdr.nl_pid == 0)
@@ -151,7 +155,9 @@ static ssize_t netlink_recv(void)
   
 
 /* family = AF_UNSPEC finds ARP table entries.
-   family = AF_LOCAL finds MAC addresses. */
+   family = AF_LOCAL finds MAC addresses.
+   returns 0 on failure, 1 on success, -1 when restart is required
+*/
 int iface_enumerate(int family, void *parm, int (*callback)())
 {
   struct sockaddr_nl addr;
@@ -159,6 +165,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
   ssize_t len;
   static unsigned int seq = 0;
   int callback_ok = 1;
+  unsigned state = 0;
 
   struct {
     struct nlmsghdr nlh;
@@ -170,7 +177,6 @@ int iface_enumerate(int family, void *parm, int (*callback)())
 
   addr.nl_family = AF_NETLINK;
  
- again: 
   if (family == AF_UNSPEC)
     req.nlh.nlmsg_type = RTM_GETNEIGH;
   else if (family == AF_LOCAL)
@@ -193,12 +199,12 @@ int iface_enumerate(int family, void *parm, int (*callback)())
     
   while (1)
     {
-      if ((len = netlink_recv()) == -1)
+      if ((len = netlink_recv(0)) == -1)
        {
          if (errno == ENOBUFS)
            {
-             sleep(1);
-             goto again;
+             nl_multicast_state(state);
+             return -1;
            }
          return 0;
        }
@@ -207,7 +213,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
        if (h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
          {
            /* May be multicast arriving async */
-           nl_async(h);
+           state = nl_async(h, state);
          }
        else if (h->nlmsg_seq != seq)
          {
@@ -341,26 +347,28 @@ int iface_enumerate(int family, void *parm, int (*callback)())
     }
 }
 
-void netlink_multicast(void)
+static void nl_multicast_state(unsigned state)
 {
   ssize_t len;
   struct nlmsghdr *h;
-  int flags;
-  
-  /* don't risk blocking reading netlink messages here. */
-  if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
-      fcntl(daemon->netlinkfd, F_SETFL, flags | O_NONBLOCK) == -1) 
-    return;
-  
-  if ((len = netlink_recv()) != -1)
-    for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
-      nl_async(h);
+
+  do {
+    /* don't risk blocking reading netlink messages here. */
+    while ((len = netlink_recv(MSG_DONTWAIT)) != -1)
   
-  /* restore non-blocking status */
-  fcntl(daemon->netlinkfd, F_SETFL, flags);
+      for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
+       state = nl_async(h, state);
+  } while (errno == ENOBUFS);
 }
 
-static void nl_async(struct nlmsghdr *h)
+void netlink_multicast(void)
+{
+  unsigned state = 0;
+  nl_multicast_state(state);
+}
+
+
+static unsigned nl_async(struct nlmsghdr *h, unsigned state)
 {
   if (h->nlmsg_type == NLMSG_ERROR)
     {
@@ -368,7 +376,8 @@ static void nl_async(struct nlmsghdr *h)
       if (err->error != 0)
        my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
     }
-  else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE) 
+  else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE &&
+          (state & STATE_NEWROUTE)==0)
     {
       /* We arrange to receive netlink multicast messages whenever the network route is added.
         If this happens and we still have a DNS packet in the buffer, we re-send it.
@@ -380,11 +389,17 @@ static void nl_async(struct nlmsghdr *h)
       if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK &&
          (rtm->rtm_table == RT_TABLE_MAIN ||
           rtm->rtm_table == RT_TABLE_LOCAL))
-       queue_event(EVENT_NEWROUTE);
+       {
+         queue_event(EVENT_NEWROUTE);
+         state |= STATE_NEWROUTE;
+       }
     }
-  else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) 
-    queue_event(EVENT_NEWADDR);
+  else if ((h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) &&
+          (state & STATE_NEWADDR)==0)
+    {
+      queue_event(EVENT_NEWADDR);
+      state |= STATE_NEWADDR;
+    }
+  return state;
 }
-#endif
-
-      
+#endif /* HAVE_LINUX_NETWORK */
index 7cf2546..3fc179d 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@ int indextoname(int fd, int index, char *name)
 
   safe_strncpy(name, ifr.ifr_name, IF_NAMESIZE);
 
 return 1;
+ return 1;
 }
 
 
@@ -232,7 +232,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
                         union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags) 
 {
   struct irec *iface;
-  int mtu = 0, loopback;
+  int loopback;
   struct ifreq ifr;
   int tftp_ok = !!option_bool(OPT_TFTP);
   int dhcp_ok = 1;
@@ -253,9 +253,6 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
   if (loopback)
     dhcp_ok = 0;
   
-  if (ioctl(param->fd, SIOCGIFMTU, &ifr) != -1)
-    mtu = ifr.ifr_mtu;
-  
   if (!label)
     label = ifr.ifr_name;
   else
@@ -351,36 +348,109 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
       /* Update addresses from interface_names. These are a set independent
         of the set we're listening on. */  
       for (int_name = daemon->int_names; int_name; int_name = int_name->next)
-       if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0 && 
-           (addr->sa.sa_family == int_name->family || int_name->family == 0))
+       if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0)
          {
-           if (param->spare)
+           struct addrlist *lp;
+
+           al = NULL;
+           
+           if (addr->sa.sa_family == AF_INET && (int_name->flags & (IN4 | INP4)))
              {
-               al = param->spare;
-               param->spare = al->next;
+               struct in_addr newaddr = addr->in.sin_addr;
+               
+               if (int_name->flags & INP4)
+                 {
+                   if (netmask.s_addr == 0xffff)
+                     continue;
+
+                   newaddr.s_addr = (addr->in.sin_addr.s_addr & netmask.s_addr) |
+                     (int_name->proto4.s_addr & ~netmask.s_addr);
+                 }
+               
+               /* check for duplicates. */
+               for (lp = int_name->addr; lp; lp = lp->next)
+                 if (lp->flags == 0 && lp->addr.addr4.s_addr == newaddr.s_addr)
+                   break;
+               
+               if (!lp)
+                 {
+                   if (param->spare)
+                     {
+                       al = param->spare;
+                       param->spare = al->next;
+                     }
+                   else
+                     al = whine_malloc(sizeof(struct addrlist));
+
+                   if (al)
+                     {
+                       al->flags = 0;
+                       al->addr.addr4 = newaddr;
+                     }
+                 }
+             }
+
+           if (addr->sa.sa_family == AF_INET6 && (int_name->flags & (IN6 | INP6)))
+             {
+               struct in6_addr newaddr = addr->in6.sin6_addr;
+               
+               if (int_name->flags & INP6)
+                 {
+                   int i;
+
+                   /* No sense in doing /128. */
+                   if (prefixlen == 128)
+                     continue;
+                   
+                   for (i = 0; i < 16; i++)
+                     {
+                       int bits = ((i+1)*8) - prefixlen;
+                      
+                       if (bits >= 8)
+                         newaddr.s6_addr[i] = int_name->proto6.s6_addr[i];
+                       else if (bits >= 0)
+                         {
+                           unsigned char mask = 0xff << bits;
+                           newaddr.s6_addr[i] =
+                             (addr->in6.sin6_addr.s6_addr[i] & mask) |
+                             (int_name->proto6.s6_addr[i] & ~mask);
+                         }
+                     }
+                 }
+               
+               /* check for duplicates. */
+               for (lp = int_name->addr; lp; lp = lp->next)
+                 if ((lp->flags & ADDRLIST_IPV6) &&
+                     IN6_ARE_ADDR_EQUAL(&lp->addr.addr6, &newaddr))
+                   break;
+                                       
+               if (!lp)
+                 {
+                   if (param->spare)
+                     {
+                       al = param->spare;
+                       param->spare = al->next;
+                     }
+                   else
+                     al = whine_malloc(sizeof(struct addrlist));
+                   
+                   if (al)
+                     {
+                       al->flags = ADDRLIST_IPV6;
+                       al->addr.addr6 = newaddr;
+
+                       /* Privacy addresses and addresses still undergoing DAD and deprecated addresses
+                          don't appear in forward queries, but will in reverse ones. */
+                       if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (IFACE_DEPRECATED | IFACE_TENTATIVE)))
+                         al->flags |= ADDRLIST_REVONLY;
+                     }
+                 }
              }
-           else
-             al = whine_malloc(sizeof(struct addrlist));
            
            if (al)
              {
                al->next = int_name->addr;
                int_name->addr = al;
-               
-               if (addr->sa.sa_family == AF_INET)
-                 {
-                   al->addr.addr4 = addr->in.sin_addr;
-                   al->flags = 0;
-                 }
-               else
-                {
-                   al->addr.addr6 = addr->in6.sin6_addr;
-                   al->flags = ADDRLIST_IPV6;
-                   /* Privacy addresses and addresses still undergoing DAD and deprecated addresses
-                      don't appear in forward queries, but will in reverse ones. */
-                   if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (IFACE_DEPRECATED | IFACE_TENTATIVE)))
-                     al->flags |= ADDRLIST_REVONLY;
-                } 
              }
          }
     }
@@ -458,6 +528,11 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
   /* add to list */
   if ((iface = whine_malloc(sizeof(struct irec))))
     {
+      int mtu = 0;
+
+      if (ioctl(param->fd, SIOCGIFMTU, &ifr) != -1)
+       mtu = ifr.ifr_mtu;
+
       iface->addr = *addr;
       iface->netmask = netmask;
       iface->tftp_ok = tftp_ok;
@@ -592,7 +667,7 @@ static int release_listener(struct listener *l)
       int port;
 
       port = prettyprint_addr(&l->iface->addr, daemon->addrbuff);
-      my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s port %d"),
+      my_syslog(LOG_DEBUG|MS_DEBUG, _("stopped listening on %s(#%d): %s port %d"),
                l->iface->name, l->iface->index, daemon->addrbuff, port);
       /* In case it ever returns */
       l->iface->done = 0;
@@ -621,7 +696,8 @@ int enumerate_interfaces(int reset)
 #ifdef HAVE_AUTH
   struct auth_zone *zone;
 #endif
-
+  struct server *serv;
+  
   /* Do this max once per select cycle  - also inhibits netlink socket use
    in TCP child processes. */
 
@@ -638,7 +714,26 @@ int enumerate_interfaces(int reset)
 
   if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
     return 0;
+
+  /* iface indexes can change when interfaces are created/destroyed. 
+     We use them in the main forwarding control path, when the path
+     to a server is specified by an interface, so cache them.
+     Update the cache here. */
+  for (serv = daemon->servers; serv; serv = serv->next)
+    if (serv->interface[0] != 0)
+      {
+#ifdef HAVE_LINUX_NETWORK
+       struct ifreq ifr;
+       
+       safe_strncpy(ifr.ifr_name, serv->interface, IF_NAMESIZE);
+       if (ioctl(param.fd, SIOCGIFINDEX, &ifr) != -1) 
+         serv->ifindex = ifr.ifr_ifindex;
+#else
+       serv->ifindex = if_nametoindex(serv->interface);
+#endif
+      }
+    
+again:
   /* Mark interfaces for garbage collection */
   for (iface = daemon->interfaces; iface; iface = iface->next) 
     iface->found = 0;
@@ -690,9 +785,14 @@ int enumerate_interfaces(int reset)
   param.spare = spare;
   
   ret = iface_enumerate(AF_INET6, &param, iface_allowed_v6);
-
-  if (ret)
-    ret = iface_enumerate(AF_INET, &param, iface_allowed_v4); 
+  if (ret < 0)
+    goto again;
+  else if (ret)
+    {
+      ret = iface_enumerate(AF_INET, &param, iface_allowed_v4);
+      if (ret < 0)
+       goto again;
+    }
  
   errsave = errno;
   close(param.fd);
@@ -727,7 +827,7 @@ int enumerate_interfaces(int reset)
 
   errno = errsave;
   spare = param.spare;
-    
+  
   return ret;
 }
 
@@ -867,10 +967,10 @@ int tcp_interface(int fd, int af)
   /* use mshdr so that the CMSDG_* macros are available */
   msg.msg_control = daemon->packet;
   msg.msg_controllen = len = daemon->packet_buff_sz;
-  
+
   /* we overwrote the buffer... */
-  daemon->srv_save = NULL;
-  
+  daemon->srv_save = NULL; 
+
   if (af == AF_INET)
     {
       if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) != -1 &&
@@ -1045,7 +1145,7 @@ void create_bound_listeners(int dienow)
             if (!dienow)
               {
                int port = prettyprint_addr(&iface->addr, daemon->addrbuff);
-               my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s port %d"),
+               my_syslog(LOG_DEBUG|MS_DEBUG, _("listening on %s(#%d): %s port %d"),
                          iface->name, iface->index, daemon->addrbuff, port);
              }
          }
@@ -1072,7 +1172,7 @@ void create_bound_listeners(int dienow)
        if (!dienow)
          {
            int port = prettyprint_addr(&if_tmp->addr, daemon->addrbuff);
-           my_syslog(LOG_DEBUG, _("listening on %s port %d"), daemon->addrbuff, port);
+           my_syslog(LOG_DEBUG|MS_DEBUG, _("listening on %s port %d"), daemon->addrbuff, port);
          }
       }
 }
@@ -1206,66 +1306,13 @@ void join_multicast(int dienow)
 }
 #endif
 
-/* return a UDP socket bound to a random port, have to cope with straying into
-   occupied port nos and reserved ones. */
-int random_sock(int family)
-{
-  int fd;
-
-  if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
-    {
-      union mysockaddr addr;
-      unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
-      int tries = ports_avail < 30 ? 3 * ports_avail : 100;
-
-      memset(&addr, 0, sizeof(addr));
-      addr.sa.sa_family = family;
-
-      /* don't loop forever if all ports in use. */
-
-      if (fix_fd(fd))
-       while(tries--)
-         {
-           unsigned short port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
-           
-           if (family == AF_INET) 
-             {
-               addr.in.sin_addr.s_addr = INADDR_ANY;
-               addr.in.sin_port = port;
-#ifdef HAVE_SOCKADDR_SA_LEN
-               addr.in.sin_len = sizeof(struct sockaddr_in);
-#endif
-             }
-           else
-             {
-               addr.in6.sin6_addr = in6addr_any; 
-               addr.in6.sin6_port = port;
-#ifdef HAVE_SOCKADDR_SA_LEN
-               addr.in6.sin6_len = sizeof(struct sockaddr_in6);
-#endif
-             }
-           
-           if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
-             return fd;
-           
-           if (errno != EADDRINUSE && errno != EACCES)
-             break;
-         }
-
-      close(fd);
-    }
-
-  return -1; 
-}
-  
-
 int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp)
 {
   union mysockaddr addr_copy = *addr;
   unsigned short port;
-  int tries = 1, done = 0;
-  unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
+  int tries = 1;
+  unsigned short ports_avail = 1;
+
   if (addr_copy.sa.sa_family == AF_INET)
     port = addr_copy.in.sin_port;
   else
@@ -1274,35 +1321,43 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind
   /* cannot set source _port_ for TCP connections. */
   if (is_tcp)
     port = 0;
-
-  /* Bind a random port within the range given by min-port and max-port */
-  if (port == 0)
+  else if (port == 0 && daemon->max_port != 0)
     {
+      /* Bind a random port within the range given by min-port and max-port if either
+        or both are set. Otherwise use the OS's random ephemeral port allocation by
+        leaving port == 0 and tries == 1 */
+      ports_avail = daemon->max_port - daemon->min_port + 1;
       tries = ports_avail < 30 ? 3 * ports_avail : 100;
-      port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
+      port = htons(daemon->min_port + (rand16() % ports_avail));
     }
   
-  while (tries--)
+  while (1)
     {
+      /* elide bind() call if it's to port 0, address 0 */
       if (addr_copy.sa.sa_family == AF_INET)
-       addr_copy.in.sin_port = port;
+       {
+         if (port == 0 && addr_copy.in.sin_addr.s_addr == 0)
+           break;
+         addr_copy.in.sin_port = port;
+       }
       else
-       addr_copy.in6.sin6_port = port;
-
-      if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) != -1)
        {
-         done = 1;
-         break;
+         if (port == 0 && IN6_IS_ADDR_UNSPECIFIED(&addr_copy.in6.sin6_addr))
+           break;
+         addr_copy.in6.sin6_port = port;
        }
       
-      if (errno != EADDRINUSE && errno != EACCES)
-       return 0;
+      if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) != -1)
+       break;
       
-      port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
-    }
+       if (errno != EADDRINUSE && errno != EACCES) 
+        return 0;
 
-  if (!done)
-    return 0;
+      if (--tries == 0)
+       return 0;
+
+      port = htons(daemon->min_port + (rand16() % ports_avail));
+    }
 
   if (!is_tcp && ifindex > 0)
     {
@@ -1332,38 +1387,33 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind
   return 1;
 }
 
-static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
+static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname, unsigned int ifindex)
 {
   struct serverfd *sfd;
-  unsigned int ifindex = 0;
   int errsave;
   int opt = 1;
   
   /* when using random ports, servers which would otherwise use
-     the INADDR_ANY/port0 socket have sfd set to NULL */
-  if (!daemon->osport && intname[0] == 0)
+     the INADDR_ANY/port0 socket have sfd set to NULL, this is 
+     anything without an explictly set source port. */
+  if (!daemon->osport)
     {
       errno = 0;
       
       if (addr->sa.sa_family == AF_INET &&
-         addr->in.sin_addr.s_addr == INADDR_ANY &&
          addr->in.sin_port == htons(0)) 
        return NULL;
 
       if (addr->sa.sa_family == AF_INET6 &&
-         memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
          addr->in6.sin6_port == htons(0)) 
        return NULL;
     }
 
-  if (intname && strlen(intname) != 0)
-    ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
-      
   /* may have a suitable one already */
   for (sfd = daemon->sfds; sfd; sfd = sfd->next )
-    if (sockaddr_isequal(&sfd->source_addr, addr) &&
-       strcmp(intname, sfd->interface) == 0 &&
-       ifindex == sfd->ifindex) 
+    if (ifindex == sfd->ifindex &&
+       sockaddr_isequal(&sfd->source_addr, addr) &&
+       strcmp(intname, sfd->interface) == 0)
       return sfd;
   
   /* need to make a new one. */
@@ -1414,7 +1464,7 @@ void pre_allocate_sfds(void)
 #ifdef HAVE_SOCKADDR_SA_LEN
       addr.in.sin_len = sizeof(struct sockaddr_in);
 #endif
-      if ((sfd = allocate_sfd(&addr, "")))
+      if ((sfd = allocate_sfd(&addr, "", 0)))
        sfd->preallocated = 1;
 
       memset(&addr, 0, sizeof(addr));
@@ -1424,13 +1474,12 @@ void pre_allocate_sfds(void)
 #ifdef HAVE_SOCKADDR_SA_LEN
       addr.in6.sin6_len = sizeof(struct sockaddr_in6);
 #endif
-      if ((sfd = allocate_sfd(&addr, "")))
+      if ((sfd = allocate_sfd(&addr, "", 0)))
        sfd->preallocated = 1;
     }
   
   for (srv = daemon->servers; srv; srv = srv->next)
-    if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
-       !allocate_sfd(&srv->source_addr, srv->interface) &&
+    if (!allocate_sfd(&srv->source_addr, srv->interface, srv->ifindex) &&
        errno != 0 &&
        option_bool(OPT_NOWILD))
       {
@@ -1445,136 +1494,23 @@ void pre_allocate_sfds(void)
       }  
 }
 
-void mark_servers(int flag)
-{
-  struct server *serv;
-
-  /* mark everything with argument flag */
-  for (serv = daemon->servers; serv; serv = serv->next)
-    {
-      if (serv->flags & flag)
-       serv->flags |= SERV_MARK;
-#ifdef HAVE_LOOP
-      /* Give looped servers another chance */
-      serv->flags &= ~SERV_LOOP;
-#endif
-    }
-}
-
-void cleanup_servers(void)
-{
-  struct server *serv, *tmp, **up;
-
-  /* unlink and free anything still marked. */
-  for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp) 
-    {
-      tmp = serv->next;
-      if (serv->flags & SERV_MARK)
-       {
-         server_gone(serv);
-         *up = serv->next;
-         if (serv->domain)
-          free(serv->domain);
-        free(serv);
-       }
-      else 
-       up = &serv->next;
-    }
-
-#ifdef HAVE_LOOP
-  /* Now we have a new set of servers, test for loops. */
-  loop_send_probes();
-#endif
-}
-
-void add_update_server(int flags,
-                      union mysockaddr *addr,
-                      union mysockaddr *source_addr,
-                      const char *interface,
-                      const char *domain)
-{
-  struct server *serv, *next = NULL;
-  char *domain_str = NULL;
-  
-  /* See if there is a suitable candidate, and unmark */
-  for (serv = daemon->servers; serv; serv = serv->next)
-    if (serv->flags & SERV_MARK)
-      {
-       if (domain)
-         {
-           if (!(serv->flags & SERV_HAS_DOMAIN) || !hostname_isequal(domain, serv->domain))
-             continue;
-         }
-       else
-         {
-           if (serv->flags & SERV_HAS_DOMAIN)
-             continue;
-         }
-       
-        break;
-      }
-
-  if (serv)
-    {
-      domain_str = serv->domain;
-      next = serv->next;
-    }
-  else if ((serv = whine_malloc(sizeof (struct server))))
-    {
-      /* Not found, create a new one. */
-      if (domain && !(domain_str = whine_malloc(strlen(domain)+1)))
-       {
-         free(serv);
-          serv = NULL;
-        }
-      else
-        {
-         struct server *s;
-         /* Add to the end of the chain, for order */
-         if (!daemon->servers)
-           daemon->servers = serv;
-         else
-           {
-             for (s = daemon->servers; s->next; s = s->next);
-             s->next = serv;
-           }
-         if (domain)
-           strcpy(domain_str, domain);
-       }
-    }
-  
-  if (serv)
-    {
-      memset(serv, 0, sizeof(struct server));
-      serv->flags = flags;
-      serv->domain = domain_str;
-      serv->next = next;
-      serv->queries = serv->failed_queries = 0;
-#ifdef HAVE_LOOP
-      serv->uid = rand32();
-#endif      
-
-      if (domain)
-       serv->flags |= SERV_HAS_DOMAIN;
-      
-      if (interface)
-       safe_strncpy(serv->interface, interface, sizeof(serv->interface));
-      if (addr)
-       serv->addr = *addr;
-      if (source_addr)
-       serv->source_addr = *source_addr;
-    }
-}
-
-void check_servers(void)
+void check_servers(int no_loop_check)
 {
   struct irec *iface;
   struct server *serv;
   struct serverfd *sfd, *tmp, **up;
   int port = 0, count;
   int locals = 0;
+  
+#ifdef HAVE_LOOP
+  if (!no_loop_check)
+    loop_send_probes();
+#endif
 
-  /* interface may be new since startup */
+  /* clear all marks. */
+  mark_servers(0);
+  
+ /* interface may be new since startup */
   if (!option_bool(OPT_NOWILD))
     enumerate_interfaces(0);
 
@@ -1584,114 +1520,117 @@ void check_servers(void)
 
   for (count = 0, serv = daemon->servers; serv; serv = serv->next)
     {
-      if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
-       {
-         /* Init edns_pktsz for newly created server records. */
-         if (serv->edns_pktsz == 0)
-           serv->edns_pktsz = daemon->edns_pktsz;
-         
+      /* Init edns_pktsz for newly created server records. */
+      if (serv->edns_pktsz == 0)
+       serv->edns_pktsz = daemon->edns_pktsz;
+      
 #ifdef HAVE_DNSSEC
-         if (option_bool(OPT_DNSSEC_VALID))
-           { 
-             if (!(serv->flags & SERV_FOR_NODOTS))
-               serv->flags |= SERV_DO_DNSSEC;
-             
-             /* Disable DNSSEC validation when using server=/domain/.... servers
-                unless there's a configured trust anchor. */
-             if (serv->flags & SERV_HAS_DOMAIN)
-               {
-                 struct ds_config *ds;
-                 char *domain = serv->domain;
-                 
-                 /* .example.com is valid */
-                 while (*domain == '.')
-                   domain++;
-                 
-                 for (ds = daemon->ds; ds; ds = ds->next)
-                   if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
-                     break;
-                 
-                 if (!ds)
-                   serv->flags &= ~SERV_DO_DNSSEC;
-               }
-           }
-#endif
-
-         port = prettyprint_addr(&serv->addr, daemon->namebuff);
-         
-         /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
-         if (serv->addr.sa.sa_family == AF_INET &&
-             serv->addr.in.sin_addr.s_addr == 0)
-           {
-             serv->flags |= SERV_MARK;
-             continue;
-           }
-
-         for (iface = daemon->interfaces; iface; iface = iface->next)
-           if (sockaddr_isequal(&serv->addr, &iface->addr))
-             break;
-         if (iface)
-           {
-             my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
-             serv->flags |= SERV_MARK;
-             continue;
-           }
+      if (option_bool(OPT_DNSSEC_VALID))
+       { 
+         if (!(serv->flags & SERV_FOR_NODOTS))
+           serv->flags |= SERV_DO_DNSSEC;
          
-         /* Do we need a socket set? */
-         if (!serv->sfd && 
-             !(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface)) &&
-             errno != 0)
+         /* Disable DNSSEC validation when using server=/domain/.... servers
+            unless there's a configured trust anchor. */
+         if (strlen(serv->domain) != 0)
            {
-             my_syslog(LOG_WARNING, 
-                       _("ignoring nameserver %s - cannot make/bind socket: %s"),
-                       daemon->namebuff, strerror(errno));
-             serv->flags |= SERV_MARK;
-             continue;
+             struct ds_config *ds;
+             char *domain = serv->domain;
+             
+             /* .example.com is valid */
+             while (*domain == '.')
+               domain++;
+             
+             for (ds = daemon->ds; ds; ds = ds->next)
+               if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
+                 break;
+             
+             if (!ds)
+               serv->flags &= ~SERV_DO_DNSSEC;
            }
-         
-         if (serv->sfd)
-           serv->sfd->used = 1;
        }
+#endif
       
-      if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
+      port = prettyprint_addr(&serv->addr, daemon->namebuff);
+      
+      /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
+      if (serv->addr.sa.sa_family == AF_INET &&
+         serv->addr.in.sin_addr.s_addr == 0)
        {
-         if (++count > SERVERS_LOGGED)
-           continue;
-         
-         if (serv->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
-           {
-             char *s1, *s2, *s3 = "";
+         serv->flags |= SERV_MARK;
+         continue;
+       }
+      
+      for (iface = daemon->interfaces; iface; iface = iface->next)
+       if (sockaddr_isequal(&serv->addr, &iface->addr))
+         break;
+      if (iface)
+       {
+         my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
+         serv->flags |= SERV_MARK;
+         continue;
+       }
+      
+      /* Do we need a socket set? */
+      if (!serv->sfd && 
+         !(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface, serv->ifindex)) &&
+         errno != 0)
+       {
+         my_syslog(LOG_WARNING, 
+                   _("ignoring nameserver %s - cannot make/bind socket: %s"),
+                   daemon->namebuff, strerror(errno));
+         serv->flags |= SERV_MARK;
+         continue;
+       }
+      
+      if (serv->sfd)
+       serv->sfd->used = 1;
+      
+      if (++count > SERVERS_LOGGED)
+       continue;
+      
+      if (strlen(serv->domain) != 0 || (serv->flags & SERV_FOR_NODOTS))
+       {
+         char *s1, *s2, *s3 = "", *s4 = "";
+
 #ifdef HAVE_DNSSEC
-             if (option_bool(OPT_DNSSEC_VALID) && !(serv->flags & SERV_DO_DNSSEC))
-               s3 = _("(no DNSSEC)");
+         if (option_bool(OPT_DNSSEC_VALID) && !(serv->flags & SERV_DO_DNSSEC))
+           s3 = _("(no DNSSEC)");
 #endif
-             if (!(serv->flags & SERV_HAS_DOMAIN))
-               s1 = _("unqualified"), s2 = _("names");
-             else if (strlen(serv->domain) == 0)
-               s1 = _("default"), s2 = "";
-             else
-               s1 = _("domain"), s2 = serv->domain;
-             
-             if (serv->flags & SERV_NO_ADDR)
-               {
-                 count--;
-                 if (++locals <= LOCALS_LOGGED)
-                       my_syslog(LOG_INFO, _("using only locally-known addresses for %s %s"), s1, s2);
-               }
-             else if (serv->flags & SERV_USE_RESOLV)
-               my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
-             else 
-               my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s %s"), daemon->namebuff, port, s1, s2, s3);
-           }
-#ifdef HAVE_LOOP
-         else if (serv->flags & SERV_LOOP)
-           my_syslog(LOG_INFO, _("NOT using nameserver %s#%d - query loop detected"), daemon->namebuff, port); 
-#endif
-         else if (serv->interface[0] != 0)
-           my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, serv->interface); 
+         if (serv->flags & SERV_FOR_NODOTS)
+           s1 = _("unqualified"), s2 = _("names");
+         else if (strlen(serv->domain) == 0)
+           s1 = _("default"), s2 = "";
          else
-           my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port); 
+           s1 = _("domain"), s2 = serv->domain, s4 = (serv->flags & SERV_WILDCARD) ? "*" : "";
+         
+         my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s%s %s"), daemon->namebuff, port, s1, s4, s2, s3);
        }
+#ifdef HAVE_LOOP
+      else if (serv->flags & SERV_LOOP)
+       my_syslog(LOG_INFO, _("NOT using nameserver %s#%d - query loop detected"), daemon->namebuff, port); 
+#endif
+      else if (serv->interface[0] != 0)
+       my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, serv->interface); 
+      else
+       my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port); 
+
+    }
+  
+  for (count = 0, serv = daemon->local_domains; serv; serv = serv->next)
+    {
+       if (++count > SERVERS_LOGGED)
+        continue;
+       
+       if ((serv->flags & SERV_LITERAL_ADDRESS) &&
+          !(serv->flags & (SERV_6ADDR | SERV_4ADDR | SERV_ALL_ZEROS)))
+        {
+          count--;
+          if (++locals <= LOCALS_LOGGED)
+            my_syslog(LOG_INFO, _("using only locally-known addresses for %s"), serv->domain);
+        }
+       else if (serv->flags & SERV_USE_RESOLV)
+        my_syslog(LOG_INFO, _("using standard nameservers for %s"), serv->domain);
     }
   
   if (locals > LOCALS_LOGGED)
@@ -1713,7 +1652,8 @@ void check_servers(void)
        up = &sfd->next;
     }
   
-  cleanup_servers();
+  cleanup_servers(); /* remove servers we just deleted. */
+  build_server_array(); 
 }
 
 /* Return zero if no servers found, in that case we keep polling.
@@ -1748,7 +1688,7 @@ int reload_servers(char *fname)
       memset(&addr, 0, sizeof(addr));
       memset(&source_addr, 0, sizeof(source_addr));
       
-      if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
+      if (inet_pton(AF_INET, token, &addr.in.sin_addr) > 0)
        {
 #ifdef HAVE_SOCKADDR_SA_LEN
          source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
@@ -1786,7 +1726,7 @@ int reload_servers(char *fname)
            continue;
        }
 
-      add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL);
+      add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL, NULL);
       gotone = 1;
     }
   
@@ -1819,8 +1759,3 @@ void newaddress(time_t now)
     lease_find_interfaces(now);
 #endif
 }
-
-
-
-
-
index 316d9c8..ffce9fc 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -168,6 +168,12 @@ struct myoption {
 #define LOPT_SINGLE_PORT   359
 #define LOPT_SCRIPT_TIME   360
 #define LOPT_PXE_VENDOR    361
+#define LOPT_DYNHOST       362
+#define LOPT_LOG_DEBUG     363
+#define LOPT_UMBRELLA     364
+#define LOPT_CMARK_ALST_EN 365
+#define LOPT_CMARK_ALST    366
+#define LOPT_QUIET_TFTP    367
  
 #ifdef HAVE_GETOPT_LONG
 static const struct option opts[] =  
@@ -321,6 +327,8 @@ static const struct myoption opts[] =
     { "auth-sec-servers", 1, 0, LOPT_AUTHSFS },
     { "auth-peer", 1, 0, LOPT_AUTHPEER }, 
     { "ipset", 1, 0, LOPT_IPSET },
+    { "connmark-allowlist-enable", 2, 0, LOPT_CMARK_ALST_EN },
+    { "connmark-allowlist", 1, 0, LOPT_CMARK_ALST },
     { "synth-domain", 1, 0, LOPT_SYNTH },
     { "dnssec", 0, 0, LOPT_SEC_VALID },
     { "trust-anchor", 1, 0, LOPT_TRUST_ANCHOR },
@@ -341,6 +349,10 @@ static const struct myoption opts[] =
     { "dumpfile", 1, 0, LOPT_DUMPFILE },
     { "dumpmask", 1, 0, LOPT_DUMPMASK },
     { "dhcp-ignore-clid", 0, 0,  LOPT_IGNORE_CLID },
+    { "dynamic-host", 1, 0, LOPT_DYNHOST },
+    { "log-debug", 0, 0, LOPT_LOG_DEBUG },
+       { "umbrella", 2, 0, LOPT_UMBRELLA },
+    { "quiet-tftp", 0, 0, LOPT_QUIET_TFTP },
     { NULL, 0, 0, 0 }
   };
 
@@ -491,6 +503,7 @@ static struct {
   { LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
   { LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
   { LOPT_HOST_REC, ARG_DUP, "<name>,<address>[,<ttl>]", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
+  { LOPT_DYNHOST, ARG_DUP, "<name>,[<IPv4>][,<IPv6>],<interface-name>", gettext_noop("Specify host record in interface subnet"), NULL },
   { LOPT_CAA, ARG_DUP, "<name>,<flags>,<tag>,<value>", gettext_noop("Specify certification authority authorization record"), NULL },  
   { LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
   { LOPT_CLVERBIND, OPT_CLEVERBIND, NULL, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL },
@@ -501,6 +514,8 @@ static struct {
   { 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>[/<domain>...]/<ipset>...", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
+  { LOPT_CMARK_ALST_EN, ARG_ONE, "[=<mask>]", gettext_noop("Enable filtering of DNS queries with connection-track marks."), NULL },
+  { LOPT_CMARK_ALST, ARG_DUP, "<connmark>[/<mask>][,<pattern>[/<pattern>...]]", gettext_noop("Set allowed DNS patterns for a connection-track mark."), 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 },
@@ -512,6 +527,7 @@ static struct {
   { 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 },
+  { LOPT_LOG_DEBUG, OPT_LOG_DEBUG, NULL, gettext_noop("Log debugging information."), NULL }, 
   { LOPT_LOCAL_SERVICE, OPT_LOCAL_SERVICE, NULL, gettext_noop("Accept queries only from directly-connected networks."), NULL },
   { LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops."), NULL },
   { LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL }, 
@@ -521,6 +537,8 @@ static struct {
   { LOPT_DUMPFILE, ARG_ONE, "<path>", gettext_noop("Path to debug packet dump file"), NULL },
   { LOPT_DUMPMASK, ARG_ONE, "<hex>", gettext_noop("Mask which packets to dump"), NULL },
   { LOPT_SCRIPT_TIME, OPT_LEASE_RENEW, NULL, gettext_noop("Call dhcp-script when lease expiry changes."), NULL },
+  { LOPT_UMBRELLA, ARG_ONE, "[=<optspec>]", gettext_noop("Send Cisco Umbrella identifiers including remote IP."), NULL },
+  { LOPT_QUIET_TFTP, OPT_QUIET_TFTP, NULL, gettext_noop("Do not log routine TFTP."), NULL },
   { 0, 0, NULL, NULL, NULL }
 }; 
 
@@ -635,6 +653,9 @@ static char *canonicalise_opt(char *s)
   if (!s)
     return 0;
 
+  if (strlen(s) == 0)
+    return opt_string_alloc("");
+
   unhide_metas(s);
   if (!(ret = canonicalise(s, &nomem)) && nomem)
     {
@@ -647,7 +668,7 @@ static char *canonicalise_opt(char *s)
   return ret;
 }
 
-static int atoi_check(char *a, int *res)
+static int numeric_check(char *a)
 {
   char *p;
 
@@ -660,10 +681,32 @@ static int atoi_check(char *a, int *res)
      if (*p < '0' || *p > '9')
        return 0;
 
+  return 1;
+}
+
+static int atoi_check(char *a, int *res)
+{
+  if (!numeric_check(a))
+    return 0;
   *res = atoi(a);
   return 1;
 }
 
+static int strtoul_check(char *a, u32 *res)
+{
+  unsigned long x;
+  
+  if (!numeric_check(a))
+    return 0;
+  x = strtoul(a, NULL, 10);
+  if (errno || x > UINT32_MAX) {
+    errno = 0;
+    return 0;
+  }
+  *res = (u32)x;
+  return 1;
+}
+
 static int atoi_check16(char *a, int *res)
 {
   if (!(atoi_check(a, res)) ||
@@ -781,21 +824,23 @@ static char *parse_mysockaddr(char *arg, union mysockaddr *addr)
   return NULL;
 }
 
-char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags)
+char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, u16 *flags)
 {
   int source_port = 0, serv_port = NAMESERVER_PORT;
   char *portno, *source;
   char *interface_opt = NULL;
   int scope_index = 0;
   char *scope_id;
-  
-  if (!arg || strlen(arg) == 0)
+
+  *interface = 0;
+
+  if (strcmp(arg, "#") == 0)
     {
-      *flags |= SERV_NO_ADDR;
-      *interface = 0;
+      if (flags)
+       *flags |= SERV_USE_RESOLV;
       return NULL;
     }
-
+  
   if ((source = split_chr(arg, '@')) && /* is there a source. */
       (portno = split_chr(source, '#')) &&
       !atoi_check16(portno, &source_port))
@@ -813,7 +858,8 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
     if (interface_opt)
       {
 #if defined(SO_BINDTODEVICE)
-       safe_strncpy(interface, interface_opt, IF_NAMESIZE);
+       safe_strncpy(interface, source, IF_NAMESIZE);
+       source = interface_opt;
 #else
        return _("interface binding not supported");
 #endif
@@ -889,66 +935,52 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
   return NULL;
 }
 
-static struct server *add_rev4(struct in_addr addr, int msize)
+static int domain_rev4(char *domain, struct in_addr addr, int msize)
 {
-  struct server *serv = opt_malloc(sizeof(struct server));
-  in_addr_t  a = ntohl(addr.s_addr);
-  char *p;
-
-  memset(serv, 0, sizeof(struct server));
-  p = serv->domain = opt_malloc(29); /* strlen("xxx.yyy.zzz.ttt.in-addr.arpa")+1 */
-
+  in_addr_t a = ntohl(addr.s_addr);
+  *domain = 0;
+  
   switch (msize)
     {
     case 32:
-      p += sprintf(p, "%u.", a & 0xff);
+      domain += sprintf(domain, "%u.", a & 0xff);
       /* fall through */
     case 24:
-      p += sprintf(p, "%d.", (a >> 8) & 0xff);
+      domain += sprintf(domain, "%d.", (a >> 8) & 0xff);
       /* fall through */
     case 16:
-      p += sprintf(p, "%d.", (a >> 16) & 0xff);
+      domain += sprintf(domain, "%d.", (a >> 16) & 0xff);
       /* fall through */
     case 8:
-      p += sprintf(p, "%d.", (a >> 24) & 0xff);
+      domain += sprintf(domain, "%d.", (a >> 24) & 0xff);
       break;
     default:
-      free(serv->domain);
-      free(serv);
-      return NULL;
+      return 0;
     }
-
-  p += sprintf(p, "in-addr.arpa");
   
-  serv->flags = SERV_HAS_DOMAIN;
-  serv->next = daemon->servers;
-  daemon->servers = serv;
-
-  return serv;
-
+  domain += sprintf(domain, "in-addr.arpa");
+  
+  return 1;
 }
 
-static struct server *add_rev6(struct in6_addr *addr, int msize)
+static int domain_rev6(char *domain, struct in6_addr *addr, int msize)
 {
-  struct server *serv = opt_malloc(sizeof(struct server));
-  char *p;
   int i;
-                                 
-  memset(serv, 0, sizeof(struct server));
-  p = serv->domain = opt_malloc(73); /* strlen("32*<n.>ip6.arpa")+1 */
+
+  if (msize > 128 || msize%4)
+    return 0;
   
+  *domain = 0;
+
   for (i = msize-1; i >= 0; i -= 4)
     { 
       int dig = ((unsigned char *)addr)[i>>3];
-      p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
+      domain += sprintf(domain, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
     }
-  p += sprintf(p, "ip6.arpa");
-  
-  serv->flags = SERV_HAS_DOMAIN;
-  serv->next = daemon->servers;
-  daemon->servers = serv;
+  domain += sprintf(domain, "ip6.arpa");
   
-  return serv;
+  return 1;
 }
 
 #ifdef HAVE_DHCP
@@ -1038,6 +1070,8 @@ static void dhcp_config_free(struct dhcp_config *config)
       
       if (config->flags & CONFIG_CLID)
         free(config->clid);
+      if (config->flags & CONFIG_NAME)
+       free(config->hostname);
 
 #ifdef HAVE_DHCP6
       if (config->flags & CONFIG_ADDR6)
@@ -1154,11 +1188,15 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
        {
          new->u.vendor_class = (unsigned char *)opt_string_alloc(arg+7);
          new->flags |= DHOPT_VENDOR;
+         if ((new->flags & DHOPT_ENCAPSULATE) || flags == DHOPT_MATCH)
+           goto_err(_("inappropriate vendor:"));
        }
       else if (strstr(arg, "encap:") == arg)
        {
          new->u.encap = atoi(arg+6);
          new->flags |= DHOPT_ENCAPSULATE;
+         if ((new->flags & DHOPT_VENDOR) || flags == DHOPT_MATCH)
+           goto_err(_("inappropriate encap:"));
        }
       else if (strstr(arg, "vi-encap:") == arg)
        {
@@ -1633,16 +1671,6 @@ void reset_option_bool(unsigned int opt)
   option_var(opt) &= ~(option_val(opt));
 }
 
-static void server_list_free(struct server *list)
-{
-  while (list)
-    {
-      struct server *tmp = list;
-      list = list->next;
-      free(tmp);
-    }
-}
-
 static int one_opt(int option, char *arg, char *errstr, char *gen_err, int command_line, int servers_only)
 {      
   int i;
@@ -2203,7 +2231,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
          arg = comma;
          comma = split(arg);
          daemon->hostmaster = opt_string_alloc(arg);
-         for (cp = daemon->hostmaster; *cp; cp++)
+         for (cp = daemon->hostmaster; cp && *cp; cp++)
            if (*cp == '@')
              *cp = '.';
 
@@ -2231,12 +2259,13 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        set_option_bool(OPT_RESOLV_DOMAIN);
       else
        {
-         char *d;
+         char *d, *d_raw = arg;
          comma = split(arg);
-         if (!(d = canonicalise_opt(arg)))
+         if (!(d = canonicalise_opt(d_raw)))
            ret_err(gen_err);
          else
            {
+             free(d); /* allocate this again below. */
              if (comma)
                {
                  struct cond_domain *new = opt_malloc(sizeof(struct cond_domain));
@@ -2244,6 +2273,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                  
                  new->prefix = NULL;
                  new->indexed = 0;
+                 new->prefixlen = 0;
                  
                  unhide_metas(comma);
                  if ((netpart = split_chr(comma, '/')))
@@ -2255,7 +2285,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                        ret_err_free(gen_err, new);
                      else if (inet_pton(AF_INET, comma, &new->start))
                        {
-                         int mask = (1 << (32 - msize)) - 1;
+                         int mask;
+
+                         if (msize > 32)
+                            ret_err_free(_("bad prefix length"), new);
+                         
+                         mask = (1 << (32 - msize)) - 1;
                          new->is6 = 0;                           
                          new->start.s_addr = ntohl(htonl(new->start.s_addr) & ~mask);
                          new->end.s_addr = new->start.s_addr | htonl(mask);
@@ -2272,41 +2307,39 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                                ret_err_free(gen_err, new);
                              else
                                {
-                                  /* generate the equivalent of
-                                     local=/xxx.yyy.zzz.in-addr.arpa/ */
-                                 struct server *serv = add_rev4(new->start, msize);
-                                 if (!serv)
-                                   ret_err_free(_("bad prefix"), new);
-
-                                 serv->flags |= SERV_NO_ADDR;
-
+                                 char domain[29]; /* strlen("xxx.yyy.zzz.ttt.in-addr.arpa")+1 */
+                                 /* local=/xxx.yyy.zzz.in-addr.arpa/ */
+                                 /* domain_rev4 can't fail here, msize checked above. */
+                                 domain_rev4(domain, new->start, msize);
+                                 add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, domain, NULL);
+                                 
                                  /* local=/<domain>/ */
-                                 serv = opt_malloc(sizeof(struct server));
-                                 memset(serv, 0, sizeof(struct server));
-                                 serv->domain = d;
-                                 serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
-                                 serv->next = daemon->servers;
-                                 daemon->servers = serv;
+                                 /* d_raw can't failed to canonicalise here, checked above. */
+                                 add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, d_raw, NULL);
                                }
                            }
                        }
                      else if (inet_pton(AF_INET6, comma, &new->start6))
                        {
-                         u64 mask = (1LLU << (128 - msize)) - 1LLU;
-                         u64 addrpart = addr6part(&new->start6);
+                         u64 mask, addrpart = addr6part(&new->start6);
+
+                         if (msize > 128)
+                           ret_err_free(_("bad prefix length"), new);
+
+                         mask = (1LLU << (128 - msize)) - 1LLU;
+
                          new->is6 = 1;
+                         new->prefixlen = msize;
                          
                          /* prefix==64 overflows the mask calculation above */
-                         if (msize == 64)
+                         if (msize <= 64)
                            mask = (u64)-1LL;
                          
                          new->end6 = new->start6;
                          setaddr6part(&new->start6, addrpart & ~mask);
                          setaddr6part(&new->end6, addrpart | mask);
                          
-                         if (msize < 64)
-                           ret_err_free(gen_err, new);
-                         else if (arg)
+                         if (arg)
                            {
                              if (option != 's')
                                {
@@ -2318,18 +2351,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                                ret_err_free(gen_err, new);
                              else 
                                {
+                                 char domain[73]; /* strlen("32*<n.>ip6.arpa")+1 */
                                  /* generate the equivalent of
                                     local=/xxx.yyy.zzz.ip6.arpa/ */
-                                 struct server *serv = add_rev6(&new->start6, msize);
-                                 serv->flags |= SERV_NO_ADDR;
-                                 
+                                 domain_rev6(domain, &new->start6, msize);
+                                 add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, domain, NULL);
+
                                  /* local=/<domain>/ */
-                                 serv = opt_malloc(sizeof(struct server));
-                                 memset(serv, 0, sizeof(struct server));
-                                 serv->domain = d;
-                                 serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
-                                 serv->next = daemon->servers;
-                                 daemon->servers = serv;
+                                 /* d_raw can't failed to canonicalise here, checked above. */
+                                 add_update_server(SERV_LITERAL_ADDRESS, NULL, NULL, NULL, d_raw, NULL);
                                }
                            }
                        }
@@ -2369,7 +2399,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                        }
                    }
 
-                 new->domain = d;
+                 new->domain = canonicalise_opt(d_raw);
                  if (option  == 's')
                    {
                      new->next = daemon->cond_domain;
@@ -2378,19 +2408,21 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                  else
                    {
                      char *star;
-                     new->next = daemon->synth_domains;
-                     daemon->synth_domains = new;
                      if (new->prefix &&
                          (star = strrchr(new->prefix, '*'))
                          && *(star+1) == 0)
                        {
                          *star = 0;
                          new->indexed = 1;
+                         if (new->is6 && new->prefixlen < 64)
+                           ret_err_free(_("prefix length too small"), new);
                        }
+                     new->next = daemon->synth_domains;
+                     daemon->synth_domains = new;
                    }
                }
              else if (option == 's')
-               daemon->domain_suffix = d;
+               daemon->domain_suffix = canonicalise_opt(d_raw);
              else 
                ret_err(gen_err);
            }
@@ -2402,6 +2434,41 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        daemon->dns_client_id = opt_string_alloc(arg);
       break;
 
+    case LOPT_UMBRELLA: /* --umbrella */
+      set_option_bool(OPT_UMBRELLA);
+      while (arg) {
+        comma = split(arg);
+        if (strstr(arg, "deviceid:")) {
+          arg += 9;
+          if (strlen(arg) != 16)
+              ret_err(gen_err);
+          for (char *p = arg; *p; p++) {
+            if (!isxdigit((int)*p))
+              ret_err(gen_err);
+          }
+          set_option_bool(OPT_UMBRELLA_DEVID);
+
+          u8 *u = daemon->umbrella_device;
+          char word[3];
+          for (u8 i = 0; i < sizeof(daemon->umbrella_device); i++, arg+=2) {
+            memcpy(word, &(arg[0]), 2);
+            *u++ = strtoul(word, NULL, 16);
+          }
+        }
+        else if (strstr(arg, "orgid:")) {
+          if (!strtoul_check(arg+6, &daemon->umbrella_org)) {
+            ret_err(gen_err);
+          }
+        }
+        else if (strstr(arg, "assetid:")) {
+          if (!strtoul_check(arg+8, &daemon->umbrella_asset)) {
+            ret_err(gen_err);
+          }
+        }
+        arg = comma;
+      }
+      break;
+
     case LOPT_ADD_MAC: /* --add-mac */
       if (!arg)
        set_option_bool(OPT_ADD_MAC);
@@ -2480,27 +2547,49 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
     case 'B':  /* --bogus-nxdomain */
     case LOPT_IGNORE_ADDR: /* --ignore-address */
      {
-       struct in_addr addr;
+       union all_addr addr;
+       int prefix, is6 = 0;
+       struct bogus_addr *baddr;
+       
        unhide_metas(arg);
-       if (arg && (inet_pton(AF_INET, arg, &addr) > 0))
+
+       if (!arg ||
+           ((comma = split_chr(arg, '/')) && !atoi_check(comma, &prefix)))
+         ret_err(gen_err);
+
+       if (inet_pton(AF_INET6, arg, &addr.addr6) == 1)
+         is6 = 1;
+       else if (inet_pton(AF_INET, arg, &addr.addr4) != 1)
+         ret_err(gen_err);
+
+       if (!comma)
          {
-           struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));
-           if (option == 'B')
-             {
-               baddr->next = daemon->bogus_addr;
-               daemon->bogus_addr = baddr;
-             }
+           if (is6)
+             prefix = 128;
            else
-             {
-               baddr->next = daemon->ignore_addr;
-               daemon->ignore_addr = baddr;
-             }
-           baddr->addr = addr;
+             prefix = 32;
+         }
+
+       if (prefix > 128 || (!is6 && prefix > 32))
+         ret_err(gen_err);
+       
+       baddr = opt_malloc(sizeof(struct bogus_addr));
+       if (option == 'B')
+         {
+           baddr->next = daemon->bogus_addr;
+           daemon->bogus_addr = baddr;
          }
        else
-         ret_err(gen_err); /* error */
-       break;  
-      }
+         {
+           baddr->next = daemon->ignore_addr;
+           daemon->ignore_addr = baddr;
+         }
+
+       baddr->prefix = prefix;
+       baddr->is6 = is6;
+       baddr->addr = addr;
+       break;
+     }
       
     case 'a':  /* --listen-address */
     case LOPT_AUTHPEER: /* --auth-peer */
@@ -2544,108 +2633,109 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
       } while (arg);
       break;
       
+    case LOPT_NO_REBIND: /*  --rebind-domain-ok */
+      {
+       struct server *new;
+
+       unhide_metas(arg);
+
+       if (*arg == '/')
+         arg++;
+       
+       do {
+         comma = split_chr(arg, '/');
+         new = opt_malloc(sizeof(struct serv_local));
+         new->domain = opt_string_alloc(arg);
+         new->domain_len = strlen(arg);
+         new->next = daemon->no_rebind;
+         daemon->no_rebind = new;
+         arg = comma;
+       } while (arg && *arg);
+
+       break;
+      }
+      
     case 'S':            /*  --server */
     case LOPT_LOCAL:     /*  --local */
     case 'A':            /*  --address */
-    case LOPT_NO_REBIND: /*  --rebind-domain-ok */
       {
-       struct server *serv, *newlist = NULL;
-       
+       char *lastdomain = NULL, *domain = "";
+       u16 flags = 0;
+       char *err;
+       union all_addr addr;
+       union mysockaddr serv_addr, source_addr;
+       char interface[IF_NAMESIZE+1];
+
        unhide_metas(arg);
        
-       if (arg && (*arg == '/' || option == LOPT_NO_REBIND))
+       /* split the domain args, if any and skip to the end of them. */
+       if (arg && *arg == '/')
          {
-           int rebind = !(*arg == '/');
-           char *end = NULL;
-           if (!rebind)
-             arg++;
-           while (rebind || (end = split_chr(arg, '/')))
-             {
-               char *domain = NULL;
-               /* elide leading dots - they are implied in the search algorithm */
-               while (*arg == '.') arg++;
-               /* # matches everything and becomes a zero length domain string */
-               if (strcmp(arg, "#") == 0)
-                 domain = "";
-               else if (strlen (arg) != 0 && !(domain = canonicalise_opt(arg)))
-                 ret_err(gen_err);
-               serv = opt_malloc(sizeof(struct server));
-               memset(serv, 0, sizeof(struct server));
-               serv->next = newlist;
-               newlist = serv;
-               serv->domain = domain;
-               serv->flags = domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
-               arg = end;
-               if (rebind)
-                 break;
-             }
-           if (!newlist)
-             ret_err(gen_err);
-         }
-       else
-         {
-           newlist = opt_malloc(sizeof(struct server));
-           memset(newlist, 0, sizeof(struct server));
-#ifdef HAVE_LOOP
-           newlist->uid = rand32();
-#endif
-         }
-       
-       if (servers_only && option == 'S')
-         newlist->flags |= SERV_FROM_FILE;
-       
-       if (option == 'A')
-         {
-           newlist->flags |= SERV_LITERAL_ADDRESS;
-           if (!(newlist->flags & SERV_TYPE))
+           char *last;
+
+           domain = lastdomain = ++arg;
+           
+           while ((last = split_chr(arg, '/')))
              {
-               server_list_free(newlist);
-               ret_err(gen_err);
+               lastdomain = arg;
+               arg = last;
              }
          }
-       else if (option == LOPT_NO_REBIND)
-         newlist->flags |= SERV_NO_REBIND;
        
        if (!arg || !*arg)
+         flags = SERV_LITERAL_ADDRESS;
+       else if (option == 'A')
          {
-           if (!(newlist->flags & SERV_NO_REBIND))
-             newlist->flags |= SERV_NO_ADDR; /* no server */
+           /* # as literal address means return zero address for 4 and 6 */
+           if (strcmp(arg, "#") == 0)
+             flags = SERV_ALL_ZEROS | SERV_LITERAL_ADDRESS;
+           else if (inet_pton(AF_INET, arg, &addr.addr4) > 0)
+             flags = SERV_4ADDR | SERV_LITERAL_ADDRESS;
+           else if (inet_pton(AF_INET6, arg, &addr.addr6) > 0)
+             flags = SERV_6ADDR | SERV_LITERAL_ADDRESS;
+           else
+             ret_err(_("Bad address in --address"));
          }
-
-       else if (strcmp(arg, "#") == 0)
-         newlist->flags |= SERV_USE_RESOLV; /* treat in ordinary way */
        else
          {
-           char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags);
-           if (err)
-             {
-               server_list_free(newlist);
-               ret_err(err);
-             }
+           if ((err = parse_server(arg, &serv_addr, &source_addr, interface, &flags)))
+             ret_err(err);
          }
+
+       if (servers_only && option == 'S')
+         flags |= SERV_FROM_FILE;
        
-       serv = newlist;
-       while (serv->next)
+       while (1)
          {
-           serv->next->flags |= serv->flags & ~(SERV_HAS_DOMAIN | SERV_FOR_NODOTS);
-           serv->next->addr = serv->addr;
-           serv->next->source_addr = serv->source_addr;
-           strcpy(serv->next->interface, serv->interface);
-           serv = serv->next;
+           /* server=//1.2.3.4 is special. */
+           if (strlen(domain) == 0 && lastdomain)
+             flags |= SERV_FOR_NODOTS;
+           else
+             flags &= ~SERV_FOR_NODOTS;
+
+           if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, &addr))
+             ret_err(gen_err);
+           
+           if (!lastdomain || domain == lastdomain)
+             break;
+           
+           domain += strlen(domain) + 1;
          }
-       serv->next = daemon->servers;
-       daemon->servers = newlist;
-       break;
+       
+       break;
       }
 
     case LOPT_REV_SERV: /* --rev-server */
       {
        char *string;
        int size;
-       struct server *serv;
+       u16 flags = 0;
+       char domain[73]; /* strlen("32*<n.>ip6.arpa")+1 */
        struct in_addr addr4;
        struct in6_addr addr6;
+       union mysockaddr serv_addr, source_addr;
+       char interface[IF_NAMESIZE+1];
+       
        unhide_metas(arg);
        if (!arg)
          ret_err(gen_err);
@@ -2657,22 +2747,27 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        
        if (inet_pton(AF_INET, arg, &addr4))
          {
-           serv = add_rev4(addr4, size);
-           if (!serv)
-             ret_err(_("bad prefix"));
+           if (!domain_rev4(domain, addr4, size))
+             ret_err(_("bad IPv4 prefix"));
          }
        else if (inet_pton(AF_INET6, arg, &addr6))
-         serv = add_rev6(&addr6, size);
+         {
+           if (!domain_rev6(domain, &addr6, size))
+             ret_err(_("bad IPv6 prefix"));
+         }
        else
          ret_err(gen_err);
-       string = parse_server(comma, &serv->addr, &serv->source_addr, serv->interface, &serv->flags);
        
-       if (string)
+       if (!comma)
+         flags |= SERV_LITERAL_ADDRESS;
+       else if ((string = parse_server(comma, &serv_addr, &source_addr, interface, &flags)))
          ret_err(string);
        
        if (servers_only)
-         serv->flags |= SERV_FROM_FILE;
+         flags |= SERV_FROM_FILE;
+
+       if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
+         ret_err(gen_err);
        
        break;
       }
@@ -2743,6 +2838,135 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
       }
 #endif
       
+    case LOPT_CMARK_ALST_EN: /* --connmark-allowlist-enable */
+#ifndef HAVE_CONNTRACK
+      ret_err(_("recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"));
+      break;
+#else
+      {
+       u32 mask = UINT32_MAX;
+       
+       if (arg)
+         if (!strtoul_check(arg, &mask) || mask < 1)
+           ret_err(gen_err);
+       
+       set_option_bool(OPT_CMARK_ALST_EN);
+       daemon->allowlist_mask = mask;
+       break;
+      }
+#endif
+      
+    case LOPT_CMARK_ALST: /* --connmark-allowlist */
+#ifndef HAVE_CONNTRACK
+       ret_err(_("recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"));
+       break;
+#else
+      {
+       struct allowlist *allowlists;
+       char **patterns, **patterns_pos;
+       u32 mark, mask = UINT32_MAX;
+       size_t num_patterns = 0;
+       
+       char *c, *m = NULL;
+       char *separator;
+       unhide_metas(arg);
+       if (!arg)
+         ret_err(gen_err);
+       c = arg;
+       if (*c < '0' || *c > '9')
+         ret_err(gen_err);
+       while (*c && *c != ',')
+         {
+           if (*c == '/')
+             {
+               if (m)
+                 ret_err(gen_err);
+               *c = '\0';
+               m = ++c;
+             }
+           if (*c < '0' || *c > '9')
+             ret_err(gen_err);
+           c++;
+         }
+       separator = c;
+       if (!*separator)
+         break;
+       while (c && *c)
+         {
+           char *end = strchr(++c, '/');
+           if (end)
+             *end = '\0';
+           if (strcmp(c, "*") && !is_valid_dns_name_pattern(c))
+             ret_err(gen_err);
+           if (end)
+             *end = '/';
+           if (num_patterns >= UINT16_MAX - 1)
+             ret_err(gen_err);
+           num_patterns++;
+           c = end;
+         }
+       
+       *separator = '\0';
+       if (!strtoul_check(arg, &mark) || mark < 1 || mark > UINT32_MAX)
+         ret_err(gen_err);
+       if (m)
+         if (!strtoul_check(m, &mask) || mask < 1 || mask > UINT32_MAX || (mark & ~mask))
+           ret_err(gen_err);
+       if (num_patterns)
+         *separator = ',';
+       for (allowlists = daemon->allowlists; allowlists; allowlists = allowlists->next)
+         if (allowlists->mark == mark && allowlists->mask == mask)
+           ret_err(gen_err);
+       
+       patterns = opt_malloc((num_patterns + 1) * sizeof(char *));
+       if (!patterns)
+         goto fail_cmark_allowlist;
+       patterns_pos = patterns;
+       c = separator;
+       while (c && *c)
+       {
+         char *end = strchr(++c, '/');
+         if (end)
+           *end = '\0';
+         if (!(*patterns_pos++ = opt_string_alloc(c)))
+           goto fail_cmark_allowlist;
+         if (end)
+           *end = '/';
+         c = end;
+       }
+       *patterns_pos++ = NULL;
+       
+       allowlists = opt_malloc(sizeof(struct allowlist));
+       if (!allowlists)
+         goto fail_cmark_allowlist;
+       memset(allowlists, 0, sizeof(struct allowlist));
+       allowlists->mark = mark;
+       allowlists->mask = mask;
+       allowlists->patterns = patterns;
+       allowlists->next = daemon->allowlists;
+       daemon->allowlists = allowlists;
+       break;
+       
+      fail_cmark_allowlist:
+       if (patterns)
+         {
+           for (patterns_pos = patterns; *patterns_pos; patterns_pos++)
+             {
+               free(*patterns_pos);
+               *patterns_pos = NULL;
+             }
+           free(patterns);
+           patterns = NULL;
+         }
+       if (allowlists)
+         {
+           free(allowlists);
+           allowlists = NULL;
+         }
+       ret_err(gen_err);
+      }
+#endif
+      
     case 'c':  /* --cache-size */
       {
        int size;
@@ -3389,7 +3613,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                for (configs = daemon->dhcp_conf; configs; configs = configs->next) 
                  if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr)
                    {
-                     sprintf(errstr, _("duplicate dhcp-host IP address %s"),  inet_ntoa(in));
+                     inet_ntop(AF_INET, &in, daemon->addrbuff, ADDRSTRLEN);
+                     sprintf(errstr, _("duplicate dhcp-host IP address %s"),
+                             daemon->addrbuff);
                      return 0;
                    }         
              }
@@ -3960,13 +4186,13 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        comma = split(arg);
        new->interface = opt_string_alloc(split(comma));
        new->iface_index = 0;
-       if (inet_pton(AF_INET, arg, &new->local) && inet_pton(AF_INET, comma, &new->server))
+       if (comma && inet_pton(AF_INET, arg, &new->local) && inet_pton(AF_INET, comma, &new->server))
          {
            new->next = daemon->relay4;
            daemon->relay4 = new;
          }
 #ifdef HAVE_DHCP6
-       else if (inet_pton(AF_INET6, arg, &new->local) && inet_pton(AF_INET6, comma, &new->server))
+       else if (comma && inet_pton(AF_INET6, arg, &new->local) && inet_pton(AF_INET6, comma, &new->server))
          {
            new->next = daemon->relay6;
            daemon->relay6 = new;
@@ -4075,36 +4301,66 @@ err:
       }
       
     case LOPT_INTNAME:  /* --interface-name */
+    case LOPT_DYNHOST:  /* --dynamic-host */
       {
        struct interface_name *new, **up;
-       char *domain = NULL;
-
-       comma = split(arg);
+       char *domain = arg;
        
-       if (!comma || !(domain = canonicalise_opt(arg)))
-         ret_err(_("bad interface name"));
+       arg = split(arg);
        
        new = opt_malloc(sizeof(struct interface_name));
-       new->next = NULL;
-       new->addr = NULL;
+       memset(new, 0, sizeof(struct interface_name));
+       new->flags = IN4 | IN6;
        
        /* Add to the end of the list, so that first name
           of an interface is used for PTR lookups. */
        for (up = &daemon->int_names; *up; up = &((*up)->next));
        *up = new;
-       new->name = domain;
-       new->family = 0;
-       arg = split_chr(comma, '/');
-       if (arg)
+       
+       while ((comma = split(arg)))
+         {
+           if (inet_pton(AF_INET, arg, &new->proto4))
+             new->flags |= INP4;
+           else if (inet_pton(AF_INET6, arg, &new->proto6))
+             new->flags |= INP6;
+           else
+             break;
+           
+           arg = comma;
+         }
+
+       if ((comma = split_chr(arg, '/')))
          {
-           if (strcmp(arg, "4") == 0)
-             new->family = AF_INET;
-           else if (strcmp(arg, "6") == 0)
-             new->family = AF_INET6;
+           if (strcmp(comma, "4") == 0)
+             new->flags &= ~IN6;
+           else if (strcmp(comma, "6") == 0)
+             new->flags &= ~IN4;
            else
              ret_err_free(gen_err, new);
-         } 
-       new->intr = opt_string_alloc(comma);
+         }
+
+       new->intr = opt_string_alloc(arg);
+
+       if (option == LOPT_DYNHOST)
+         {
+           if (!(new->flags & (INP4 | INP6)))
+             ret_err(_("missing address in dynamic host"));
+
+           if (!(new->flags & IN4) || !(new->flags & IN6))
+             arg = NULL; /* provoke error below */
+
+           new->flags &= ~(IN4 | IN6);
+         }
+       else
+         {
+           if (new->flags & (INP4 | INP6))
+             arg = NULL; /* provoke error below */
+         }
+       
+       if (!domain || !arg || !(new->name = canonicalise_opt(domain)))
+         ret_err(option == LOPT_DYNHOST ?
+                 _("bad dynamic host") : _("bad interface name"));
+       
        break;
       }
       
@@ -4431,8 +4687,7 @@ err:
              }
            else
              {
-               int nomem;
-               char *canon = canonicalise(arg, &nomem);
+               char *canon = canonicalise_opt(arg);
                struct name_list *nl;
                if (!canon)
                   {
@@ -4773,15 +5028,33 @@ static int one_file(char *file, int hard_opt)
   return 1;
 }
 
+static int file_filter(const struct dirent *ent)
+{
+  size_t lenfile = strlen(ent->d_name);
+
+  /* ignore emacs backups and dotfiles */
+
+  if (lenfile == 0 || 
+      ent->d_name[lenfile - 1] == '~' ||
+      (ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
+      ent->d_name[0] == '.')
+    return 0;
+
+  return 1;
+}
 /* expand any name which is a directory */
 struct hostsfile *expand_filelist(struct hostsfile *list)
 {
   unsigned int i;
-  struct hostsfile *ah;
+  int entcnt, n;
+  struct hostsfile *ah, *last, *next, **up;
+  struct dirent **namelist;
 
   /* find largest used index */
   for (i = SRC_AH, ah = list; ah; ah = ah->next)
     {
+      last = ah;
+      
       if (i <= ah->index)
        i = ah->index + 1;
 
@@ -4797,46 +5070,48 @@ struct hostsfile *expand_filelist(struct hostsfile *list)
        struct stat buf;
        if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode))
          {
-           DIR *dir_stream;
            struct dirent *ent;
            
            /* don't read this as a file */
            ah->flags |= AH_INACTIVE;
            
-           if (!(dir_stream = opendir(ah->fname)))
+           entcnt = scandir(ah->fname, &namelist, file_filter, alphasort);
+           if (entcnt < 0)
              my_syslog(LOG_ERR, _("cannot access directory %s: %s"), 
                        ah->fname, strerror(errno));
            else
              {
-               while ((ent = readdir(dir_stream)))
+               for (n = 0; n < entcnt; n++)
                  {
+                   ent = namelist[n];
                    size_t lendir = strlen(ah->fname);
                    size_t lenfile = strlen(ent->d_name);
                    struct hostsfile *ah1;
                    char *path;
                    
-                   /* ignore emacs backups and dotfiles */
-                   if (lenfile == 0 || 
-                       ent->d_name[lenfile - 1] == '~' ||
-                       (ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
-                       ent->d_name[0] == '.')
-                     continue;
-                   
                    /* see if we have an existing record.
                       dir is ah->fname 
                       file is ent->d_name
                       path to match is ah1->fname */
                    
-                   for (ah1 = list; ah1; ah1 = ah1->next)
+                   for (up = &list, ah1 = list; ah1; ah1 = next)
                      {
+                       next = ah1->next;
+
                        if (lendir < strlen(ah1->fname) &&
                            strstr(ah1->fname, ah->fname) == ah1->fname &&
                            ah1->fname[lendir] == '/' &&
                            strcmp(ah1->fname + lendir + 1, ent->d_name) == 0)
                          {
                            ah1->flags &= ~AH_INACTIVE;
+                           /* If found, remove from list to re-insert at the end.
+                              Unless it's already at the end. */
+                           if (last != ah1)
+                             *up = next;
                            break;
                          }
+
+                       up = &ah1->next;
                      }
                    
                    /* make new record */
@@ -4857,17 +5132,21 @@ struct hostsfile *expand_filelist(struct hostsfile *list)
                        ah1->fname = path;
                        ah1->index = i++;
                        ah1->flags = AH_DIR;
-                       ah1->next = list;
-                       list = ah1;
                      }
+
+                   /* Edge case, may be the last in the list anyway */
+                   if (last != ah1)
+                     last->next = ah1;
+                   ah1->next = NULL;
+                   last = ah1;
                    
                    /* inactivate record if not regular file */
                    if ((ah1->flags & AH_DIR) && stat(ah1->fname, &buf) != -1 && !S_ISREG(buf.st_mode))
                      ah1->flags |= AH_INACTIVE; 
                    
                  }
-               closedir(dir_stream);
              }
+           free(namelist);
          }
       }
   
@@ -4885,9 +5164,9 @@ void read_servers_file(void)
     }
   
   mark_servers(SERV_FROM_FILE);
-  cleanup_servers();
-  
   read_file(daemon->servers_file, f, LOPT_REV_SERV);
+  cleanup_servers();
+  check_servers(0);
 }
  
 
@@ -4903,30 +5182,8 @@ static void clear_dynamic_conf(void)
       
       if (configs->flags & CONFIG_BANK)
        {
-         struct hwaddr_config *mac, *tmp;
-         struct dhcp_netid_list *list, *tmplist;
-         
-         for (mac = configs->hwaddr; mac; mac = tmp)
-           {
-             tmp = mac->next;
-             free(mac);
-           }
-         
-         if (configs->flags & CONFIG_CLID)
-           free(configs->clid);
-         
-         for (list = configs->netid; list; list = tmplist)
-           {
-             free(list->list);
-             tmplist = list->next;
-             free(list);
-           }
-         
-         if (configs->flags & CONFIG_NAME)
-           free(configs->hostname);
-         
-         *up = configs->next;
-         free(configs);
+         *up = cp;
+         dhcp_config_free(configs);
        }
       else
        up = &configs->next;
@@ -4936,7 +5193,6 @@ static void clear_dynamic_conf(void)
 static void clear_dynamic_opt(void)
 {
   struct dhcp_opt *opts, *cp, **up;
-  struct dhcp_netid *id, *next;
 
   for (up = &daemon->dhcp_opts, opts = daemon->dhcp_opts; opts; opts = cp)
     {
@@ -4944,17 +5200,8 @@ static void clear_dynamic_opt(void)
       
       if (opts->flags & DHOPT_BANK)
        {
-         if ((opts->flags & DHOPT_VENDOR))
-           free(opts->u.vendor_class);
-         free(opts->val);
-         for (id = opts->netid; id; id = next)
-           {
-             next = id->next;
-             free(id->net);
-             free(id);
-           }
-         *up = opts->next;
-         free(opts);
+         *up = cp;
+         dhcp_opt_free(opts);
        }
       else
        up = &opts->next;
@@ -5014,7 +5261,8 @@ void read_opts(int argc, char **argv, char *compile_opts)
   daemon = opt_malloc(sizeof(struct daemon));
   memset(daemon, 0, sizeof(struct daemon));
   daemon->namebuff = buff;
-
+  daemon->addrbuff = safe_malloc(ADDRSTRLEN);
+  
   /* Set defaults - everything else is zero or NULL */
   daemon->cachesize = CACHESIZ;
   daemon->ftabsize = FTABSIZ;
@@ -5034,9 +5282,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
   daemon->soa_refresh = SOA_REFRESH;
   daemon->soa_retry = SOA_RETRY;
   daemon->soa_expiry = SOA_EXPIRY;
-  daemon->max_port = MAX_PORT;
-  daemon->min_port = MIN_PORT;
-
+  
 #ifndef NO_ID
   add_txt("version.bind", "dnsmasq-" VERSION, 0 );
   add_txt("authors.bind", "Simon Kelley", 0);
index 50513dc..da6f73c 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/src/pattern.c b/src/pattern.c
new file mode 100644 (file)
index 0000000..03e23b9
--- /dev/null
@@ -0,0 +1,386 @@
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 dated June, 1991, or
+   (at your option) version 3 dated 29 June, 2007.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+     
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "dnsmasq.h"
+
+#ifdef HAVE_CONNTRACK
+
+#define LOG(...) \
+  do { \
+    my_syslog(LOG_DEBUG, __VA_ARGS__); \
+  } while (0)
+
+#define ASSERT(condition) \
+  do { \
+    if (!(condition)) \
+      my_syslog(LOG_ERR, _("[pattern.c:%d] Assertion failure: %s"), __LINE__, #condition); \
+  } while (0)
+
+/**
+ * Determines whether a given string value matches against a glob pattern
+ * which may contain zero-or-more-character wildcards denoted by '*'.
+ *
+ * Based on "Glob Matching Can Be Simple And Fast Too" by Russ Cox,
+ * See https://research.swtch.com/glob
+ *
+ * @param      value                A string value.
+ * @param      num_value_bytes      The number of bytes of the string value.
+ * @param      pattern              A glob pattern.
+ * @param      num_pattern_bytes    The number of bytes of the glob pattern.
+ *
+ * @return 1                        If the provided value matches against the glob pattern.
+ * @return 0                        Otherwise.
+ */
+static int is_string_matching_glob_pattern(
+  const char *value,
+  size_t num_value_bytes,
+  const char *pattern,
+  size_t num_pattern_bytes)
+{
+  ASSERT(value);
+  ASSERT(pattern);
+  
+  size_t value_index = 0;
+  size_t next_value_index = 0;
+  size_t pattern_index = 0;
+  size_t next_pattern_index = 0;
+  while (value_index < num_value_bytes || pattern_index < num_pattern_bytes)
+    {
+      if (pattern_index < num_pattern_bytes)
+       {
+         char pattern_character = pattern[pattern_index];
+         if ('a' <= pattern_character && pattern_character <= 'z')
+           pattern_character -= 'a' - 'A';
+         if (pattern_character == '*')
+           {
+             /* zero-or-more-character wildcard */
+             /* Try to match at value_index, otherwise restart at value_index + 1 next. */
+             next_pattern_index = pattern_index;
+             pattern_index++;
+             if (value_index < num_value_bytes)
+               next_value_index = value_index + 1;
+             else
+               next_value_index = 0;
+             continue;
+           }
+         else
+           {
+             /* ordinary character */
+             if (value_index < num_value_bytes)
+               {
+                 char value_character = value[value_index];
+                 if ('a' <= value_character && value_character <= 'z')
+                   value_character -= 'a' - 'A';
+                 if (value_character == pattern_character)
+                   {
+                     pattern_index++;
+                     value_index++;
+                     continue;
+                   }
+               }
+           }
+       }
+      if (next_value_index)
+       {
+         pattern_index = next_pattern_index;
+         value_index = next_value_index;
+         continue;
+       }
+      return 0;
+    }
+  return 1;
+}
+
+/**
+ * Determines whether a given string value represents a valid DNS name.
+ *
+ * - DNS names must adhere to RFC 1123: 1 to 253 characters in length, consisting of a sequence of labels
+ *   delimited by dots ("."). Each label must be 1 to 63 characters in length, contain only
+ *   ASCII letters ("a"-"Z"), digits ("0"-"9"), or hyphens ("-") and must not start or end with a hyphen.
+ *
+ * - A valid name must be fully qualified, i.e., consist of at least two labels.
+ *   The final label must not be fully numeric, and must not be the "local" pseudo-TLD.
+ *
+ * - Examples:
+ *   Valid: "example.com"
+ *   Invalid: "ipcamera", "ipcamera.local", "8.8.8.8"
+ *
+ * @param      value                A string value.
+ *
+ * @return 1                        If the provided string value is a valid DNS name.
+ * @return 0                        Otherwise.
+ */
+int is_valid_dns_name(const char *value)
+{
+  ASSERT(value);
+  
+  size_t num_bytes = 0;
+  size_t num_labels = 0;
+  const char *label = NULL;
+  int is_label_numeric = 1;
+  for (const char *c = value;; c++)
+    {
+      if (*c &&
+         *c != '-' && *c != '.' &&
+         (*c < '0' || *c > '9') &&
+         (*c < 'A' || *c > 'Z') &&
+         (*c < 'a' || *c > 'z'))
+       {
+         LOG(_("Invalid DNS name: Invalid character %c."), *c);
+         return 0;
+       }
+      if (*c)
+       num_bytes++;
+      if (!label)
+       {
+         if (!*c || *c == '.')
+           {
+             LOG(_("Invalid DNS name: Empty label."));
+             return 0;
+           }
+         if (*c == '-')
+           {
+             LOG(_("Invalid DNS name: Label starts with hyphen."));
+             return 0;
+           }
+         label = c;
+       }
+      if (*c && *c != '.')
+       {
+         if (*c < '0' || *c > '9')
+           is_label_numeric = 0;
+       }
+      else
+       {
+         if (c[-1] == '-')
+           {
+             LOG(_("Invalid DNS name: Label ends with hyphen."));
+             return 0;
+           }
+         size_t num_label_bytes = (size_t) (c - label);
+         if (num_label_bytes > 63)
+           {
+             LOG(_("Invalid DNS name: Label is too long (%zu)."), num_label_bytes);
+             return 0;
+           }
+         num_labels++;
+         if (!*c)
+           {
+             if (num_labels < 2)
+               {
+                 LOG(_("Invalid DNS name: Not enough labels (%zu)."), num_labels);
+                 return 0;
+               }
+             if (is_label_numeric)
+               {
+                 LOG(_("Invalid DNS name: Final label is fully numeric."));
+                 return 0;
+               }
+             if (num_label_bytes == 5 &&
+                 (label[0] == 'l' || label[0] == 'L') &&
+                 (label[1] == 'o' || label[1] == 'O') &&
+                 (label[2] == 'c' || label[2] == 'C') &&
+                 (label[3] == 'a' || label[3] == 'A') &&
+                 (label[4] == 'l' || label[4] == 'L'))
+               {
+                 LOG(_("Invalid DNS name: \"local\" pseudo-TLD."));
+                 return 0;
+               }
+             if (num_bytes < 1 || num_bytes > 253)
+               {
+                 LOG(_("DNS name has invalid length (%zu)."), num_bytes);
+                 return 0;
+               }
+             return 1;
+           }
+         label = NULL;
+         is_label_numeric = 1;
+       }
+    }
+}
+
+/**
+ * Determines whether a given string value represents a valid DNS name pattern.
+ *
+ * - DNS names must adhere to RFC 1123: 1 to 253 characters in length, consisting of a sequence of labels
+ *   delimited by dots ("."). Each label must be 1 to 63 characters in length, contain only
+ *   ASCII letters ("a"-"Z"), digits ("0"-"9"), or hyphens ("-") and must not start or end with a hyphen.
+ *
+ * - Patterns follow the syntax of DNS names, but additionally allow the wildcard character "*" to be used up to
+ *   twice per label to match 0 or more characters within that label. Note that the wildcard never matches a dot
+ *   (e.g., "*.example.com" matches "api.example.com" but not "api.us.example.com").
+ *
+ * - A valid name or pattern must be fully qualified, i.e., consist of at least two labels.
+ *   The final label must not be fully numeric, and must not be the "local" pseudo-TLD.
+ *   A pattern must end with at least two literal (non-wildcard) labels.
+ *
+ * - Examples:
+ *   Valid: "example.com", "*.example.com", "video*.example.com", "api*.*.example.com", "*-prod-*.example.com"
+ *   Invalid: "ipcamera", "ipcamera.local", "*", "*.com", "8.8.8.8"
+ *
+ * @param      value                A string value.
+ *
+ * @return 1                        If the provided string value is a valid DNS name pattern.
+ * @return 0                        Otherwise.
+ */
+int is_valid_dns_name_pattern(const char *value)
+{
+  ASSERT(value);
+  
+  size_t num_bytes = 0;
+  size_t num_labels = 0;
+  const char *label = NULL;
+  int is_label_numeric = 1;
+  size_t num_wildcards = 0;
+  int previous_label_has_wildcard = 1;
+  for (const char *c = value;; c++)
+    {
+      if (*c &&
+         *c != '*' && /* Wildcard. */
+         *c != '-' && *c != '.' &&
+         (*c < '0' || *c > '9') &&
+         (*c < 'A' || *c > 'Z') &&
+         (*c < 'a' || *c > 'z'))
+       {
+         LOG(_("Invalid DNS name pattern: Invalid character %c."), *c);
+         return 0;
+       }
+      if (*c && *c != '*')
+       num_bytes++;
+      if (!label)
+       {
+         if (!*c || *c == '.')
+           {
+             LOG(_("Invalid DNS name pattern: Empty label."));
+             return 0;
+           }
+         if (*c == '-')
+           {
+             LOG(_("Invalid DNS name pattern: Label starts with hyphen."));
+             return 0;
+           }
+         label = c;
+       }
+      if (*c && *c != '.')
+       {
+         if (*c < '0' || *c > '9')
+           is_label_numeric = 0;
+         if (*c == '*')
+           {
+             if (num_wildcards >= 2)
+               {
+                 LOG(_("Invalid DNS name pattern: Wildcard character used more than twice per label."));
+                 return 0;
+               }
+             num_wildcards++;
+           }
+       }
+      else
+       {
+         if (c[-1] == '-')
+           {
+             LOG(_("Invalid DNS name pattern: Label ends with hyphen."));
+             return 0;
+           }
+         size_t num_label_bytes = (size_t) (c - label) - num_wildcards;
+         if (num_label_bytes > 63)
+           {
+             LOG(_("Invalid DNS name pattern: Label is too long (%zu)."), num_label_bytes);
+             return 0;
+           }
+         num_labels++;
+         if (!*c)
+           {
+             if (num_labels < 2)
+               {
+                 LOG(_("Invalid DNS name pattern: Not enough labels (%zu)."), num_labels);
+                 return 0;
+               }
+             if (num_wildcards != 0 || previous_label_has_wildcard)
+               {
+                 LOG(_("Invalid DNS name pattern: Wildcard within final two labels."));
+                 return 0;
+               }
+             if (is_label_numeric)
+               {
+                 LOG(_("Invalid DNS name pattern: Final label is fully numeric."));
+                 return 0;
+               }
+             if (num_label_bytes == 5 &&
+                 (label[0] == 'l' || label[0] == 'L') &&
+                 (label[1] == 'o' || label[1] == 'O') &&
+                 (label[2] == 'c' || label[2] == 'C') &&
+                 (label[3] == 'a' || label[3] == 'A') &&
+                 (label[4] == 'l' || label[4] == 'L'))
+               {
+                 LOG(_("Invalid DNS name pattern: \"local\" pseudo-TLD."));
+                 return 0;
+               }
+             if (num_bytes < 1 || num_bytes > 253)
+               {
+                 LOG(_("DNS name pattern has invalid length after removing wildcards (%zu)."), num_bytes);
+                 return 0;
+               }
+             return 1;
+           }
+           label = NULL;
+           is_label_numeric = 1;
+           previous_label_has_wildcard = num_wildcards != 0;
+           num_wildcards = 0;
+         }
+    }
+}
+
+/**
+ * Determines whether a given DNS name matches against a DNS name pattern.
+ *
+ * @param      name                 A valid DNS name.
+ * @param      pattern              A valid DNS name pattern.
+ *
+ * @return 1                        If the provided DNS name matches against the DNS name pattern.
+ * @return 0                        Otherwise.
+ */
+int is_dns_name_matching_pattern(const char *name, const char *pattern)
+{
+  ASSERT(name);
+  ASSERT(is_valid_dns_name(name));
+  ASSERT(pattern);
+  ASSERT(is_valid_dns_name_pattern(pattern));
+  
+  const char *n = name;
+  const char *p = pattern;
+  
+  do {
+    const char *name_label = n;
+    while (*n && *n != '.')
+      n++;
+    const char *pattern_label = p;
+    while (*p && *p != '.')
+      p++;
+    if (!is_string_matching_glob_pattern(
+        name_label, (size_t) (n - name_label),
+        pattern_label, (size_t) (p - pattern_label)))
+      break;
+    if (*n)
+      n++;
+    if (*p)
+      p++;
+  } while (*n && *p);
+  
+  return !*n && !*p;
+}
+
+#endif
index 24d01bb..f414690 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
index edc1532..8314e8a 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -53,6 +53,3 @@ struct prefix_opt {
 #define ICMP6_OPT_RT_INFO     24
 #define ICMP6_OPT_RDNSS       25
 #define ICMP6_OPT_DNSSL       31
-
-
-
index 41df852..3255904 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
index 79af53f..6fc4f26 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -364,7 +364,7 @@ int private_net(struct in_addr addr, int ban_localhost)
 
   return
     (((ip_addr & 0xFF000000) == 0x7F000000) && ban_localhost)  /* 127.0.0.0/8    (loopback) */ ||
-    ((ip_addr & 0xFF000000) == 0x00000000)  /* RFC 5735 section 3. "here" network */ ||
+    (((ip_addr & 0xFF000000) == 0x00000000) && ban_localhost) /* RFC 5735 section 3. "here" network */ ||
     ((ip_addr & 0xFF000000) == 0x0A000000)  /* 10.0.0.0/8     (private)  */ ||
     ((ip_addr & 0xFFF00000) == 0xAC100000)  /* 172.16.0.0/12  (private)  */ ||
     ((ip_addr & 0xFFFF0000) == 0xC0A80000)  /* 192.168.0.0/16 (private)  */ ||
@@ -375,28 +375,32 @@ int private_net(struct in_addr addr, int ban_localhost)
     ((ip_addr & 0xFFFFFFFF) == 0xFFFFFFFF)  /* 255.255.255.255/32 (broadcast)*/ ;
 }
 
-static int private_net6(struct in6_addr *a)
+static int private_net6(struct in6_addr *a, int ban_localhost)
 {
-  return 
-    IN6_IS_ADDR_UNSPECIFIED(a) || /* RFC 6303 4.3 */
-    IN6_IS_ADDR_LOOPBACK(a) ||    /* RFC 6303 4.3 */
+  /* Block IPv4-mapped IPv6 addresses in private IPv4 address space */
+  if (IN6_IS_ADDR_V4MAPPED(a))
+    {
+      struct in_addr v4;
+      v4.s_addr = ((const uint32_t *) (a))[3];
+      return private_net(v4, ban_localhost);
+    }
+
+  return
+    (IN6_IS_ADDR_UNSPECIFIED(a) && ban_localhost) || /* RFC 6303 4.3 */
+    (IN6_IS_ADDR_LOOPBACK(a) && ban_localhost) ||    /* RFC 6303 4.3 */
     IN6_IS_ADDR_LINKLOCAL(a) ||   /* RFC 6303 4.5 */
+    IN6_IS_ADDR_SITELOCAL(a) ||
     ((unsigned char *)a)[0] == 0xfd ||   /* RFC 6303 4.4 */
     ((u32 *)a)[0] == htonl(0x20010db8); /* RFC 6303 4.6 */
 }
 
-static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, char *name, int *doctored)
+static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, int *doctored)
 {
   int i, qtype, qclass, rdlen;
 
   for (i = count; i != 0; i--)
     {
-      if (name && option_bool(OPT_LOG))
-       {
-         if (!extract_name(header, qlen, &p, name, 1, 10))
-           return 0;
-       }
-      else if (!(p = skip_name(p, header, qlen, 10)))
+      if (!(p = skip_name(p, header, qlen, 10)))
        return 0; /* bad packet */
       
       GETSHORT(qtype, p); 
@@ -435,34 +439,6 @@ static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *
              break;
            }
        }
-      else if (qtype == T_TXT && name && option_bool(OPT_LOG))
-       {
-         unsigned char *p1 = p;
-         if (!CHECK_LEN(header, p1, qlen, rdlen))
-           return 0;
-         while ((p1 - p) < rdlen)
-           {
-             unsigned int i, len = *p1;
-             unsigned char *p2 = p1;
-             if ((p1 + len - p) >= rdlen)
-               return 0; /* bad packet */
-             /* make counted string zero-term  and sanitise */
-             for (i = 0; i < len; i++)
-               {
-                 if (!isprint((int)*(p2+1)))
-                   break;
-                 
-                 *p2 = *(p2+1);
-                 p2++;
-               }
-             *p2 = 0;
-             my_syslog(LOG_INFO, "reply %s is %s", name, p1);
-             /* restore */
-             memmove(p1 + 1, p1, i);
-             *p1 = len;
-             p1 += len+1;
-           }
-       }                 
       
       if (!ADD_RDLEN(header, p, qlen, rdlen))
         return 0; /* bad packet */
@@ -471,7 +447,7 @@ static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *
   return p; 
 }
 
-static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doctored)
+static int find_soa(struct dns_header *header, size_t qlen, int *doctored)
 {
   unsigned char *p;
   int qtype, qclass, rdlen;
@@ -480,7 +456,7 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doc
   
   /* first move to NS section and find TTL from any SOA section */
   if (!(p = skip_questions(header, qlen)) ||
-      !(p = do_doctor(p, ntohs(header->ancount), header, qlen, name, doctored)))
+      !(p = do_doctor(p, ntohs(header->ancount), header, qlen, doctored)))
     return 0;  /* bad packet */
   
   for (i = ntohs(header->nscount); i != 0; i--)
@@ -516,7 +492,7 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doc
     }
   
   /* rewrite addresses in additional section too */
-  if (!do_doctor(p, ntohs(header->arcount), header, qlen, NULL, doctored))
+  if (!do_doctor(p, ntohs(header->arcount), header, qlen, doctored))
     return 0;
   
   if (!found_soa)
@@ -525,6 +501,40 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doc
   return minttl;
 }
 
+/* Print TXT reply to log */
+static int print_txt(struct dns_header *header, const size_t qlen, char *name,
+                    unsigned char *p, const int ardlen, int secflag)
+{
+  unsigned char *p1 = p;
+  if (!CHECK_LEN(header, p1, qlen, ardlen))
+    return 0;
+  /* Loop over TXT payload */
+  while ((p1 - p) < ardlen)
+    {
+      unsigned int i, len = *p1;
+      unsigned char *p3 = p1;
+      if ((p1 + len - p) >= ardlen)
+       return 0; /* bad packet */
+
+      /* make counted string zero-term and sanitise */
+      for (i = 0; i < len; i++)
+       {
+         if (!isprint((int)*(p3+1)))
+           break;
+         *p3 = *(p3+1);
+         p3++;
+       }
+
+      *p3 = 0;
+      log_query(secflag | F_FORWARD | F_UPSTREAM, name, NULL, (char*)p1);
+      /* restore */
+      memmove(p1 + 1, p1, i);
+      *p1 = len;
+      p1 += len+1;
+    }
+  return 1;
+}
+
 /* Note that the following code can create CNAME chains that don't point to a real record,
    either because of lack of memory, or lack of SOA records.  These are treated by the cache code as 
    expired and cleaned out that way. 
@@ -534,7 +544,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
                      int secure, int *doctored)
 {
   unsigned char *p, *p1, *endrr, *namep;
-  int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
+  int j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
   unsigned long ttl = 0;
   union all_addr addr;
 #ifdef HAVE_IPSET
@@ -542,15 +552,21 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
 #else
   (void)ipsets; /* unused */
 #endif
-
+  int found = 0, cname_count = CNAME_CHAIN;
+  struct crec *cpp = NULL;
+  int flags = RCODE(header) == NXDOMAIN ? F_NXDOMAIN : 0;
+#ifdef HAVE_DNSSEC
+  int cname_short = 0;
+#endif
+  unsigned long cttl = ULONG_MAX, attl;
   
   cache_start_insert();
 
-  /* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
-  if (daemon->doctors || option_bool(OPT_LOG) || option_bool(OPT_DNSSEC_VALID))
+  /* find_soa is needed for dns_doctor side effects, so don't call it lazily if there are any. */
+  if (daemon->doctors || option_bool(OPT_DNSSEC_VALID))
     {
       searched_soa = 1;
-      ttl = find_soa(header, qlen, name, doctored);
+      ttl = find_soa(header, qlen, doctored);
 
       if (*doctored)
        {
@@ -558,308 +574,329 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
            return 0;
 #ifdef HAVE_DNSSEC
          if (option_bool(OPT_DNSSEC_VALID))
-           for (i = 0; i < ntohs(header->ancount); i++)
-             if (daemon->rr_status[i] != 0)
+           for (j = 0; j < ntohs(header->ancount); j++)
+             if (daemon->rr_status[j] != 0)
                return 0;
 #endif
        }
     }
   
-  /* go through the questions. */
-  p = (unsigned char *)(header+1);
+  namep = p = (unsigned char *)(header+1);
   
-  for (i = ntohs(header->qdcount); i != 0; i--)
-    {
-      int found = 0, cname_count = CNAME_CHAIN;
-      struct crec *cpp = NULL;
-      int flags = RCODE(header) == NXDOMAIN ? F_NXDOMAIN : 0;
-#ifdef HAVE_DNSSEC
-      int cname_short = 0;
-#endif
-      unsigned long cttl = ULONG_MAX, attl;
-
-      namep = p;
-      if (!extract_name(header, qlen, &p, name, 1, 4))
-       return 0; /* bad packet */
-           
-      GETSHORT(qtype, p); 
-      GETSHORT(qclass, p);
+  if (ntohs(header->qdcount) != 1 || !extract_name(header, qlen, &p, name, 1, 4))
+    return 0; /* bad packet */
+  
+  GETSHORT(qtype, p); 
+  GETSHORT(qclass, p);
+  
+  if (qclass != C_IN)
+    return 0;
+  
+  /* PTRs: we chase CNAMEs here, since we have no way to 
+     represent them in the cache. */
+  if (qtype == T_PTR)
+    { 
+      int insert = 1, name_encoding = in_arpa_name_2_addr(name, &addr);
       
-      if (qclass != C_IN)
-       continue;
-
-      /* PTRs: we chase CNAMEs here, since we have no way to 
-        represent them in the cache. */
-      if (qtype == T_PTR)
-       { 
-         int name_encoding = in_arpa_name_2_addr(name, &addr);
+      if (!(flags & F_NXDOMAIN))
+       {
+       cname_loop:
+         if (!(p1 = skip_questions(header, qlen)))
+           return 0;
          
-         if (!name_encoding)
-           continue;
-
-         if (!(flags & F_NXDOMAIN))
+         for (j = 0; j < ntohs(header->ancount); j++) 
            {
-           cname_loop:
-             if (!(p1 = skip_questions(header, qlen)))
-               return 0;
+             int secflag = 0;
+             if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
+               return 0; /* bad packet */
              
-             for (j = 0; j < ntohs(header->ancount); j++) 
+             GETSHORT(aqtype, p1); 
+             GETSHORT(aqclass, p1);
+             GETLONG(attl, p1);
+             
+             if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
                {
-                 int secflag = 0;
-                 unsigned char *tmp = namep;
-                 /* the loop body overwrites the original name, so get it back here. */
-                 if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
-                     !(res = extract_name(header, qlen, &p1, name, 0, 10)))
-                   return 0; /* bad packet */
-                 
-                 GETSHORT(aqtype, p1); 
-                 GETSHORT(aqclass, p1);
-                 GETLONG(attl, p1);
-                 if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
+                 (p1) -= 4;
+                 PUTLONG(daemon->max_ttl, p1);
+               }
+             GETSHORT(ardlen, p1);
+             endrr = p1+ardlen;
+             
+             /* TTL of record is minimum of CNAMES and PTR */
+             if (attl < cttl)
+               cttl = attl;
+             
+             if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
+               {
+#ifdef HAVE_DNSSEC
+                 if (option_bool(OPT_DNSSEC_VALID) && !no_cache_dnssec && daemon->rr_status[j] != 0)
                    {
-                     (p1) -= 4;
-                     PUTLONG(daemon->max_ttl, p1);
+                     /* validated RR anywhere in CNAME chain, don't cache. */
+                     if (cname_short || aqtype == T_CNAME)
+                       insert = 0;
+                     
+                     secflag = F_DNSSECOK;
+                     /* limit TTL based on signature. */
+                     if (daemon->rr_status[j] < cttl)
+                       cttl = daemon->rr_status[j];
                    }
-                 GETSHORT(ardlen, p1);
-                 endrr = p1+ardlen;
-                 
-                 /* TTL of record is minimum of CNAMES and PTR */
-                 if (attl < cttl)
-                   cttl = attl;
-
-                 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
-                   {
-                     if (!extract_name(header, qlen, &p1, name, 1, 0))
-                       return 0;
-#ifdef HAVE_DNSSEC
-                     if (option_bool(OPT_DNSSEC_VALID) && daemon->rr_status[j] != 0)
-                       {
-                         /* validated RR anywhere in CNAME chain, don't cache. */
-                         if (cname_short || aqtype == T_CNAME)
-                           return 0;
-
-                         secflag = F_DNSSECOK;
-                         /* limit TTL based on signature. */
-                         if (daemon->rr_status[j] < cttl)
-                           cttl = daemon->rr_status[j];
-                       }
 #endif
 
-                     if (aqtype == T_CNAME)
-                       {
-                         if (!cname_count--)
-                           return 0; /* looped CNAMES, we can't cache. */
+                 if (aqtype == T_CNAME)
+                   log_query(secflag | F_CNAME | F_FORWARD | F_UPSTREAM, name, NULL, NULL);
+                 
+                 if (!extract_name(header, qlen, &p1, name, 1, 0))
+                   return 0;
+                 
+                 if (aqtype == T_CNAME)
+                   {
+                     if (!cname_count--)
+                       return 0; /* looped CNAMES, we can't cache. */
 #ifdef HAVE_DNSSEC
-                         cname_short = 1;
+                     cname_short = 1;
 #endif
-                         goto cname_loop;
-                       }
-                     
-                     cache_insert(name, &addr, C_IN, now, cttl, name_encoding | secflag | F_REVERSE);
-                     found = 1; 
+                     goto cname_loop;
                    }
                  
-                 p1 = endrr;
-                 if (!CHECK_LEN(header, p1, qlen, 0))
-                   return 0; /* bad packet */
+                 found = 1; 
+                 
+                 if (!name_encoding)
+                   log_query(secflag | F_FORWARD | F_UPSTREAM, name, NULL, querystr(NULL, aqtype));
+                 else
+                   {
+                     log_query(name_encoding | secflag | F_REVERSE | F_UPSTREAM, name, &addr, NULL);
+                     if (insert)
+                       cache_insert(name, &addr, C_IN, now, cttl, name_encoding | secflag | F_REVERSE);
+                   }
                }
+
+             p1 = endrr;
+             if (!CHECK_LEN(header, p1, qlen, 0))
+               return 0; /* bad packet */
+           }
+       }
+      
+      if (!found && !option_bool(OPT_NO_NEG))
+       {
+         if (!searched_soa)
+           {
+             searched_soa = 1;
+             ttl = find_soa(header, qlen, doctored);
            }
          
-          if (!found && !option_bool(OPT_NO_NEG))
+         flags |= F_NEG | (secure ?  F_DNSSECOK : 0);
+         if (name_encoding && ttl)
            {
-             if (!searched_soa)
-               {
-                 searched_soa = 1;
-                 ttl = find_soa(header, qlen, NULL, doctored);
-               }
-             if (ttl)
-               cache_insert(NULL, &addr, C_IN, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | (secure ?  F_DNSSECOK : 0));      
+             flags |= F_REVERSE | name_encoding;
+             cache_insert(NULL, &addr, C_IN, now, ttl, flags);
            }
+         
+         log_query(flags | F_UPSTREAM, name, &addr, NULL);
+       }
+    }
+  else
+    {
+      /* everything other than PTR */
+      struct crec *newc;
+      int addrlen = 0, insert = 1;
+      
+      if (qtype == T_A)
+       {
+         addrlen = INADDRSZ;
+         flags |= F_IPV4;
+       }
+      else if (qtype == T_AAAA)
+       {
+         addrlen = IN6ADDRSZ;
+         flags |= F_IPV6;
        }
+      else if (qtype == T_SRV)
+       flags |= F_SRV;
       else
+       insert = 0; /* NOTE: do not cache data from CNAME queries. */
+      
+    cname_loop1:
+      if (!(p1 = skip_questions(header, qlen)))
+       return 0;
+      
+      for (j = 0; j < ntohs(header->ancount); j++) 
        {
-         /* everything other than PTR */
-         struct crec *newc;
-         int addrlen = 0;
-
-         if (qtype == T_A)
+         int secflag = 0;
+         
+         if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
+           return 0; /* bad packet */
+         
+         GETSHORT(aqtype, p1); 
+         GETSHORT(aqclass, p1);
+         GETLONG(attl, p1);
+         if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
            {
-             addrlen = INADDRSZ;
-             flags |= F_IPV4;
+             (p1) -= 4;
+             PUTLONG(daemon->max_ttl, p1);
            }
-         else if (qtype == T_AAAA)
+         GETSHORT(ardlen, p1);
+         endrr = p1+ardlen;
+         
+         /* Not what we're looking for? */
+         if (aqclass != C_IN || res == 2)
            {
-             addrlen = IN6ADDRSZ;
-             flags |= F_IPV6;
+             p1 = endrr;
+             if (!CHECK_LEN(header, p1, qlen, 0))
+               return 0; /* bad packet */
+             continue;
            }
-         else if (qtype == T_SRV)
-           flags |= F_SRV;
-         else
-           continue;
-           
-       cname_loop1:
-         if (!(p1 = skip_questions(header, qlen)))
-           return 0;
          
-         for (j = 0; j < ntohs(header->ancount); j++) 
+#ifdef HAVE_DNSSEC
+         if (option_bool(OPT_DNSSEC_VALID) && !no_cache_dnssec && daemon->rr_status[j] != 0)
            {
-             int secflag = 0;
+             secflag = F_DNSSECOK;
              
-             if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
-               return 0; /* bad packet */
+             /* limit TTl based on sig. */
+             if (daemon->rr_status[j] < attl)
+               attl = daemon->rr_status[j];
+           }
+#endif   
+         
+         if (aqtype == T_CNAME)
+           {
+             if (!cname_count--)
+               return 0; /* looped CNAMES */
              
-             GETSHORT(aqtype, p1); 
-             GETSHORT(aqclass, p1);
-             GETLONG(attl, p1);
-             if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
-               {
-                 (p1) -= 4;
-                 PUTLONG(daemon->max_ttl, p1);
-               }
-             GETSHORT(ardlen, p1);
-             endrr = p1+ardlen;
+             log_query(secflag | F_CNAME | F_FORWARD | F_UPSTREAM, name, NULL, NULL);
              
-             if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
+             if (insert)
                {
-#ifdef HAVE_DNSSEC
-                 if (option_bool(OPT_DNSSEC_VALID) && daemon->rr_status[j] != 0)
+                 if ((newc = cache_insert(name, NULL, C_IN, now, attl, F_CNAME | F_FORWARD | secflag)))
                    {
-                     secflag = F_DNSSECOK;
-
-                     /* limit TTl based on sig. */
-                     if (daemon->rr_status[j] < attl)
-                       attl = daemon->rr_status[j];
-                   }
-#endif           
-                 if (aqtype == T_CNAME)
-                   {
-                     if (!cname_count--)
-                       return 0; /* looped CNAMES */
-
-                     if ((newc = cache_insert(name, NULL, C_IN, now, attl, F_CNAME | F_FORWARD | secflag)))
+                     newc->addr.cname.target.cache = NULL;
+                     newc->addr.cname.is_name_ptr = 0; 
+                     if (cpp)
                        {
-                         newc->addr.cname.target.cache = NULL;
-                         newc->addr.cname.is_name_ptr = 0; 
-                         if (cpp)
-                           {
-                             next_uid(newc);
-                             cpp->addr.cname.target.cache = newc;
-                             cpp->addr.cname.uid = newc->uid;
-                           }
+                         next_uid(newc);
+                         cpp->addr.cname.target.cache = newc;
+                         cpp->addr.cname.uid = newc->uid;
                        }
-                     
-                     cpp = newc;
-                     if (attl < cttl)
-                       cttl = attl;
-                     
-                     namep = p1;
-                     if (!extract_name(header, qlen, &p1, name, 1, 0))
-                       return 0;
-                     
-                     goto cname_loop1;
                    }
-                 else if (!(flags & F_NXDOMAIN))
+                 
+                 cpp = newc;
+                 if (attl < cttl)
+                   cttl = attl;
+               }
+             
+             namep = p1;
+             if (!extract_name(header, qlen, &p1, name, 1, 0))
+               return 0;
+             
+             goto cname_loop1;
+           }
+         else if (aqtype != qtype)
+           {
+#ifdef HAVE_DNSSEC
+             if (!option_bool(OPT_DNSSEC_VALID) || aqtype != T_RRSIG)
+#endif
+               log_query(secflag | F_FORWARD | F_UPSTREAM, name, NULL, querystr(NULL, aqtype));
+           }
+         else if (!(flags & F_NXDOMAIN))
+           {
+             found = 1;
+             
+             if (flags & F_SRV)
+               {
+                 unsigned char *tmp = namep;
+                 
+                 if (!CHECK_LEN(header, p1, qlen, 6))
+                   return 0; /* bad packet */
+                 GETSHORT(addr.srv.priority, p1);
+                 GETSHORT(addr.srv.weight, p1);
+                 GETSHORT(addr.srv.srvport, p1);
+                 if (!extract_name(header, qlen, &p1, name, 1, 0))
+                   return 0;
+                 addr.srv.targetlen = strlen(name) + 1; /* include terminating zero */
+                 if (!(addr.srv.target = blockdata_alloc(name, addr.srv.targetlen)))
+                   return 0;
+                 
+                 /* we overwrote the original name, so get it back here. */
+                 if (!extract_name(header, qlen, &tmp, name, 1, 0))
+                   return 0;
+               }
+             else if (flags & (F_IPV4 | F_IPV6))
+               {
+                 /* copy address into aligned storage */
+                 if (!CHECK_LEN(header, p1, qlen, addrlen))
+                   return 0; /* bad packet */
+                 memcpy(&addr, p1, addrlen);
+                 
+                 /* check for returned address in private space */
+                 if (check_rebind)
                    {
-                     found = 1;
+                     if ((flags & F_IPV4) &&
+                         private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
+                       return 1;
                      
-                     if (flags & F_SRV)
-                       {
-                          unsigned char *tmp = namep;
-
-                          if (!CHECK_LEN(header, p1, qlen, 6))
-                            return 0; /* bad packet */
-                          GETSHORT(addr.srv.priority, p1);
-                          GETSHORT(addr.srv.weight, p1);
-                          GETSHORT(addr.srv.srvport, p1);
-                          if (!extract_name(header, qlen, &p1, name, 1, 0))
-                            return 0;
-                          addr.srv.targetlen = strlen(name) + 1; /* include terminating zero */
-                          if (!(addr.srv.target = blockdata_alloc(name, addr.srv.targetlen)))
-                            return 0;
-                          
-                          /* we overwrote the original name, so get it back here. */
-                          if (!extract_name(header, qlen, &tmp, name, 1, 0))
-                            return 0;
-                       }
-                     else
-                       {
-                         /* copy address into aligned storage */
-                         if (!CHECK_LEN(header, p1, qlen, addrlen))
-                           return 0; /* bad packet */
-                         memcpy(&addr, p1, addrlen);
-                     
-                         /* check for returned address in private space */
-                         if (check_rebind)
-                           {
-                             if ((flags & F_IPV4) &&
-                                 private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
-                               return 1;
-
-                             /* Block IPv4-mapped IPv6 addresses in private IPv4 address space */
-                             if (flags & F_IPV6)
-                               {
-                                 if (IN6_IS_ADDR_V4MAPPED(&addr.addr6))
-                                   {
-                                     struct in_addr v4;
-                                     v4.s_addr = ((const uint32_t *) (&addr.addr6))[3];
-                                     if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
-                                       return 1;
-                                   }
-
-                                 /* Check for link-local (LL) and site-local (ULA) IPv6 addresses */
-                                 if (IN6_IS_ADDR_LINKLOCAL(&addr.addr6) ||
-                                     IN6_IS_ADDR_SITELOCAL(&addr.addr6))
-                                   return 1;
-
-                                 /* Check for the IPv6 loopback address (::1) when
-                                    option rebind-localhost-ok is NOT set */
-                                 if (!option_bool(OPT_LOCAL_REBIND) &&
-                                     IN6_IS_ADDR_LOOPBACK(&addr.addr6))
-                                   return 1;
-                               }
-                           }
-
+                     if ((flags & F_IPV6) &&
+                         private_net6(&addr.addr6, !option_bool(OPT_LOCAL_REBIND)))
+                       return 1;
+                   }
+                 
 #ifdef HAVE_IPSET
-                         if (ipsets && (flags & (F_IPV4 | F_IPV6)))
-                           {
-                             ipsets_cur = ipsets;
-                             while (*ipsets_cur)
-                               {
-                                 log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
-                                 add_to_ipset(*ipsets_cur++, &addr, flags, 0);
-                               }
-                           }
-#endif
-                       }
-                     
-                     newc = cache_insert(name, &addr, C_IN, now, attl, flags | F_FORWARD | secflag);
-                     if (newc && cpp)
+                 if (ipsets && (flags & (F_IPV4 | F_IPV6)))
+                   {
+                     ipsets_cur = ipsets;
+                     while (*ipsets_cur)
                        {
-                         next_uid(newc);
-                         cpp->addr.cname.target.cache = newc;
-                         cpp->addr.cname.uid = newc->uid;
+                         log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
+                         add_to_ipset(*ipsets_cur++, &addr, flags, 0);
                        }
-                     cpp = NULL;
                    }
+#endif
                }
              
-             p1 = endrr;
-             if (!CHECK_LEN(header, p1, qlen, 0))
-               return 0; /* bad packet */
+             if (insert)
+               {
+                 newc = cache_insert(name, &addr, C_IN, now, attl, flags | F_FORWARD | secflag);
+                 if (newc && cpp)
+                   {
+                     next_uid(newc);
+                     cpp->addr.cname.target.cache = newc;
+                     cpp->addr.cname.uid = newc->uid;
+                   }
+                 cpp = NULL;
+               }
+             
+             if (aqtype == T_TXT)
+               {
+                 if (!print_txt(header, qlen, name, p1, ardlen, secflag))
+                   return 0;
+               }
+             else
+               log_query(flags | F_FORWARD | secflag | F_UPSTREAM, name, &addr, querystr(NULL, aqtype));
            }
          
-         if (!found && !option_bool(OPT_NO_NEG))
+         p1 = endrr;
+         if (!CHECK_LEN(header, p1, qlen, 0))
+           return 0; /* bad packet */
+       }
+      
+      if (!found && !option_bool(OPT_NO_NEG))
+       {
+         if (!searched_soa)
            {
-             if (!searched_soa)
-               {
-                 searched_soa = 1;
-                 ttl = find_soa(header, qlen, NULL, doctored);
-               }
-             /* If there's no SOA to get the TTL from, but there is a CNAME 
-                pointing at this, inherit its TTL */
-             if (ttl || cpp)
+             searched_soa = 1;
+             ttl = find_soa(header, qlen, doctored);
+           }
+         
+         /* If there's no SOA to get the TTL from, but there is a CNAME 
+            pointing at this, inherit its TTL */
+         if (ttl || cpp)
+           {
+             if (ttl == 0)
+               ttl = cttl;
+             
+             log_query(F_UPSTREAM | F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0), name, NULL, NULL);
+             
+             if (insert)
                {
-                 newc = cache_insert(name, NULL, C_IN, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));  
+                 newc = cache_insert(name, NULL, C_IN, now, ttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));       
                  if (newc && cpp)
                    {
                      next_uid(newc);
@@ -884,6 +921,92 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
   return 0;
 }
 
+#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
+/* Don't pass control chars and weird escapes to UBus. */
+static int safe_name(char *name)
+{
+  unsigned char *r;
+  
+  for (r = (unsigned char *)name; *r; r++)
+    if (!isprint((int)*r))
+      return 0;
+  
+  return 1;
+}
+
+void report_addresses(struct dns_header *header, size_t len, u32 mark)
+{
+  unsigned char *p, *endrr;
+  int i;
+  unsigned long attl;
+  struct allowlist *allowlists;
+  char **pattern_pos;
+  
+  if (RCODE(header) != NOERROR)
+    return;
+  
+  for (allowlists = daemon->allowlists; allowlists; allowlists = allowlists->next)
+    if (allowlists->mark == (mark & daemon->allowlist_mask & allowlists->mask))
+      for (pattern_pos = allowlists->patterns; *pattern_pos; pattern_pos++)
+       if (!strcmp(*pattern_pos, "*"))
+         return;
+  
+  if (!(p = skip_questions(header, len)))
+    return;
+  for (i = ntohs(header->ancount); i != 0; i--)
+    {
+      int aqtype, aqclass, ardlen;
+      
+      if (!extract_name(header, len, &p, daemon->namebuff, 1, 10))
+       return;
+      
+      if (!CHECK_LEN(header, p, len, 10))
+       return;
+      GETSHORT(aqtype, p);
+      GETSHORT(aqclass, p);
+      GETLONG(attl, p);
+      GETSHORT(ardlen, p);
+      
+      if (!CHECK_LEN(header, p, len, ardlen))
+       return;
+      endrr = p+ardlen;
+      
+      if (aqclass == C_IN)
+       {
+         if (aqtype == T_CNAME)
+           {
+             if (!extract_name(header, len, &p, daemon->workspacename, 1, 0))
+               return;
+             if (safe_name(daemon->namebuff) && safe_name(daemon->workspacename))
+               ubus_event_bcast_connmark_allowlist_resolved(mark, daemon->namebuff, daemon->workspacename, attl);
+           }
+         if (aqtype == T_A)
+           {
+             struct in_addr addr;
+             char ip[INET_ADDRSTRLEN];
+             if (ardlen != INADDRSZ)
+               return;
+             memcpy(&addr, p, ardlen);
+             if (inet_ntop(AF_INET, &addr, ip, sizeof ip) && safe_name(daemon->namebuff))
+               ubus_event_bcast_connmark_allowlist_resolved(mark, daemon->namebuff, ip, attl);
+           }
+         else if (aqtype == T_AAAA)
+           {
+             struct in6_addr addr;
+             char ip[INET6_ADDRSTRLEN];
+             if (ardlen != IN6ADDRSZ)
+               return;
+             memcpy(&addr, p, ardlen);
+             if (inet_ntop(AF_INET6, &addr, ip, sizeof ip) && safe_name(daemon->namebuff))
+               ubus_event_bcast_connmark_allowlist_resolved(mark, daemon->namebuff, ip, attl);
+           }
+       }
+      
+      p = endrr;
+    }
+}
+#endif
+
 /* If the packet holds exactly one query
    return F_IPV4 or F_IPV6  and leave the name from the query in name */
 unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, unsigned short *typep)
@@ -894,9 +1017,14 @@ unsigned int extract_request(struct dns_header *header, size_t qlen, char *name,
   if (typep)
     *typep = 0;
 
+  *name = 0; /* return empty name if no query found. */
+  
   if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
     return 0; /* must be exactly one query. */
   
+  if (!(header->hb3 & HB3_QR) && (ntohs(header->ancount) != 0 || ntohs(header->nscount) != 0))
+    return 0; /* non-standard query. */
+  
   if (!extract_name(header, qlen, &p, name, 1, 4))
     return 0; /* bad packet */
    
@@ -916,24 +1044,20 @@ unsigned int extract_request(struct dns_header *header, size_t qlen, char *name,
        return  F_IPV4 | F_IPV6;
     }
 
+#ifdef HAVE_DNSSEC
   /* F_DNSSECOK as agument to search_servers() inhibits forwarding
      to servers for domains without a trust anchor. This make the
      behaviour for DS and DNSKEY queries we forward the same
      as for DS and DNSKEY queries we originate. */
-  if (qtype == T_DS || qtype == T_DNSKEY)
+  if (option_bool(OPT_DNSSEC_VALID) && (qtype == T_DS || qtype == T_DNSKEY))
     return F_DNSSECOK;
+#endif
   
   return F_QUERY;
 }
 
-size_t setup_reply(struct dns_header *header, size_t qlen,
-                  union all_addr *addrp, unsigned int flags, unsigned long ttl)
+void setup_reply(struct dns_header *header, unsigned int flags, int ede)
 {
-  unsigned char *p;
-  
-  if (!(p = skip_questions(header, qlen)))
-    return 0;
-  
   /* clear authoritative and truncated flags, set QR flag */
   header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC )) | HB3_QR;
   /* clear AD flag, set RA flag */
@@ -946,40 +1070,19 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
     SET_RCODE(header, NOERROR); /* empty domain */
   else if (flags == F_NXDOMAIN)
     SET_RCODE(header, NXDOMAIN);
-  else if (flags == F_SERVFAIL)
-    {
-      union all_addr a;
-      a.log.rcode = SERVFAIL;
-      log_query(F_CONFIG | F_RCODE, "error", &a, NULL);
-      SET_RCODE(header, SERVFAIL);
-    }
   else if (flags & ( F_IPV4 | F_IPV6))
     {
-      if (flags & F_IPV4)
-       { /* we know the address */
-         SET_RCODE(header, NOERROR);
-         header->ancount = htons(1);
-         header->hb3 |= HB3_AA;
-         add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp);
-       }
-      
-      if (flags & F_IPV6)
-       {
-         SET_RCODE(header, NOERROR);
-         header->ancount = htons(ntohs(header->ancount) + 1);
-         header->hb3 |= HB3_AA;
-         add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
-       }
+      SET_RCODE(header, NOERROR);
+      header->hb3 |= HB3_AA;
     }
   else /* nowhere to forward to */
     {
       union all_addr a;
       a.log.rcode = REFUSED;
+      a.log.ede = ede;
       log_query(F_CONFIG | F_RCODE, "error", &a, NULL);
       SET_RCODE(header, REFUSED);
     }
-  
-  return p - (unsigned char *)header;
 }
 
 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
@@ -1017,47 +1120,61 @@ int check_for_local_domain(char *name, time_t now)
   return 0;
 }
 
-/* Is the packet a reply with the answer address equal to addr?
-   If so mung is into an NXDOMAIN reply and also put that information
-   in the cache. */
-int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, 
-                            struct bogus_addr *baddr, time_t now)
+static int check_bad_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr, char *name, unsigned long *ttlp)
 {
   unsigned char *p;
   int i, qtype, qclass, rdlen;
   unsigned long ttl;
   struct bogus_addr *baddrp;
-
+  
   /* skip over questions */
   if (!(p = skip_questions(header, qlen)))
     return 0; /* bad packet */
 
   for (i = ntohs(header->ancount); i != 0; i--)
     {
-      if (!extract_name(header, qlen, &p, name, 1, 10))
+      if (name && !extract_name(header, qlen, &p, name, 1, 10))
        return 0; /* bad packet */
-  
+
+      if (!name && !(p = skip_name(p, header, qlen, 10)))
+       return 0;
+      
       GETSHORT(qtype, p); 
       GETSHORT(qclass, p);
       GETLONG(ttl, p);
       GETSHORT(rdlen, p);
+
+      if (ttlp)
+       *ttlp = ttl;
       
-      if (qclass == C_IN && qtype == T_A)
+      if (qclass == C_IN)
        {
-         if (!CHECK_LEN(header, p, qlen, INADDRSZ))
-           return 0;
-         
-         for (baddrp = baddr; baddrp; baddrp = baddrp->next)
-           if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
-             {
-               /* Found a bogus address. Insert that info here, since there no SOA record
-                  to get the ttl from in the normal processing */
-               cache_start_insert();
-               cache_insert(name, NULL, C_IN, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
-               cache_end_insert();
-               
-               return 1;
-             }
+         if (qtype == T_A)
+           {
+             struct in_addr addr;
+             
+             if (!CHECK_LEN(header, p, qlen, INADDRSZ))
+               return 0;
+
+             memcpy(&addr, p, INADDRSZ);
+
+             for (baddrp = baddr; baddrp; baddrp = baddrp->next)
+               if (!baddrp->is6 && is_same_net_prefix(addr, baddrp->addr.addr4, baddrp->prefix))
+                 return 1;
+           }
+         else if (qtype == T_AAAA)
+           {
+             struct in6_addr addr;
+             
+             if (!CHECK_LEN(header, p, qlen, IN6ADDRSZ))
+               return 0;
+
+             memcpy(&addr, p, IN6ADDRSZ);
+
+             for (baddrp = baddr; baddrp; baddrp = baddrp->next)
+               if (baddrp->is6 && is_same_net6(&addr, &baddrp->addr.addr6, baddrp->prefix))
+                 return 1;
+           }
        }
       
       if (!ADD_RDLEN(header, p, qlen, rdlen))
@@ -1067,43 +1184,31 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
   return 0;
 }
 
-int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr)
+/* Is the packet a reply with the answer address equal to addr?
+   If so mung is into an NXDOMAIN reply and also put that information
+   in the cache. */
+int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, time_t now)
 {
-  unsigned char *p;
-  int i, qtype, qclass, rdlen;
-  struct bogus_addr *baddrp;
-
-  /* skip over questions */
-  if (!(p = skip_questions(header, qlen)))
-    return 0; /* bad packet */
+  unsigned long ttl;
 
-  for (i = ntohs(header->ancount); i != 0; i--)
+  if (check_bad_address(header, qlen, daemon->bogus_addr, name, &ttl))
     {
-      if (!(p = skip_name(p, header, qlen, 10)))
-       return 0; /* bad packet */
-      
-      GETSHORT(qtype, p); 
-      GETSHORT(qclass, p);
-      p += 4; /* TTL */
-      GETSHORT(rdlen, p);
-      
-      if (qclass == C_IN && qtype == T_A)
-       {
-         if (!CHECK_LEN(header, p, qlen, INADDRSZ))
-           return 0;
-         
-         for (baddrp = baddr; baddrp; baddrp = baddrp->next)
-           if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
-             return 1;
-       }
-      
-      if (!ADD_RDLEN(header, p, qlen, rdlen))
-       return 0;
+      /* Found a bogus address. Insert that info here, since there no SOA record
+        to get the ttl from in the normal processing */
+      cache_start_insert();
+      cache_insert(name, NULL, C_IN, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
+      cache_end_insert();
+
+      return 1;
     }
-  
+
   return 0;
 }
 
+int check_for_ignored_address(struct dns_header *header, size_t qlen)
+{
+  return check_bad_address(header, qlen, daemon->ignore_addr, NULL, NULL);
+}
 
 int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp, 
                        unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
@@ -1566,43 +1671,17 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                              anscount++;
                    }
                }
-             else if (option_bool(OPT_BOGUSPRIV) && (
-                      (is_arpa == F_IPV6 && private_net6(&addr.addr6)) ||
-                      (is_arpa == F_IPV4 && private_net(addr.addr4, 1))))
+             else if (option_bool(OPT_BOGUSPRIV) &&
+                      ((is_arpa == F_IPV6 && private_net6(&addr.addr6, 1)) || (is_arpa == F_IPV4 && private_net(addr.addr4, 1))) &&
+                      !lookup_domain(name, F_DOMAINSRV, NULL, NULL))
                {
-                 struct server *serv;
-                 unsigned int namelen = strlen(name);
-                 char *nameend = name + namelen;
-
-                 /* see if have rev-server set */
-                 for (serv = daemon->servers; serv; serv = serv->next)
-                   {
-                     unsigned int domainlen;
-                     char *matchstart;
-
-                     if ((serv->flags & (SERV_HAS_DOMAIN | SERV_NO_ADDR)) != SERV_HAS_DOMAIN)
-                       continue;
-
-                     domainlen = strlen(serv->domain);
-                     if (domainlen == 0 || domainlen > namelen)
-                       continue;
-
-                     matchstart = nameend - domainlen;
-                     if (hostname_isequal(matchstart, serv->domain) &&
-                         (namelen == domainlen || *(matchstart-1) == '.' ))
-                       break;
-                   }
-
                  /* if no configured server, not in cache, enabled and private IPV4 address, return NXDOMAIN */
-                 if (!serv)
-                   {
-                     ans = 1;
-                     sec_data = 0;
-                     nxdomain = 1;
-                     if (!dryrun)
-                       log_query(F_CONFIG | F_REVERSE | is_arpa | F_NEG | F_NXDOMAIN,
-                                 name, &addr, NULL);
-                   }
+                 ans = 1;
+                 sec_data = 0;
+                 nxdomain = 1;
+                 if (!dryrun)
+                   log_query(F_CONFIG | F_REVERSE | is_arpa | F_NEG | F_NXDOMAIN,
+                             name, &addr, NULL);
                }
            }
 
index d678068..c902eb7 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -372,9 +372,22 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
   
   if (!context)
     {
-      my_syslog(MS_DHCP | LOG_WARNING, _("no address range available for DHCP request %s %s"), 
-               subnet_addr.s_addr ? _("with subnet selector") : _("via"),
-               subnet_addr.s_addr ? inet_ntoa(subnet_addr) : (mess->giaddr.s_addr ? inet_ntoa(mess->giaddr) : iface_name));
+      const char *via;
+      if (subnet_addr.s_addr)
+       {
+         via = _("with subnet selector");
+         inet_ntop(AF_INET, &subnet_addr, daemon->addrbuff, ADDRSTRLEN);
+       }
+      else
+       {
+         via = _("via");
+         if (mess->giaddr.s_addr)
+           inet_ntop(AF_INET, &mess->giaddr, daemon->addrbuff, ADDRSTRLEN);
+         else
+           safe_strncpy(daemon->addrbuff, iface_name, ADDRSTRLEN);
+       }
+      my_syslog(MS_DHCP | LOG_WARNING, _("no address range available for DHCP request %s %s"),
+               via, daemon->addrbuff);
       return 0;
     }
 
@@ -383,13 +396,19 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
       struct dhcp_context *context_tmp;
       for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
        {
-         strcpy(daemon->namebuff, inet_ntoa(context_tmp->start));
+         inet_ntop(AF_INET, &context_tmp->start, daemon->namebuff, MAXDNAME);
          if (context_tmp->flags & (CONTEXT_STATIC | CONTEXT_PROXY))
-           my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP subnet: %s/%s"),
-                     ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->netmask));
+           {
+             inet_ntop(AF_INET, &context_tmp->netmask, daemon->addrbuff, ADDRSTRLEN);
+             my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP subnet: %s/%s"),
+                       ntohl(mess->xid), daemon->namebuff, daemon->addrbuff);
+           }
          else
-           my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP range: %s -- %s"), 
-                     ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->end));
+           {
+             inet_ntop(AF_INET, &context_tmp->end, daemon->addrbuff, ADDRSTRLEN);
+             my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP range: %s -- %s"),
+                       ntohl(mess->xid), daemon->namebuff, daemon->addrbuff);
+           }
        }
     }
   
@@ -1031,8 +1050,9 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
          config->addr.s_addr == option_addr(opt).s_addr)
        {
          prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
+         inet_ntop(AF_INET, &config->addr, daemon->addrbuff, ADDRSTRLEN);
          my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"), 
-                   inet_ntoa(config->addr), daemon->dhcp_buff);
+                   daemon->addrbuff, daemon->dhcp_buff);
          config->flags |= CONFIG_DECLINED;
          config->decline_time = now;
        }
@@ -1078,7 +1098,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
          
          if (have_config(config, CONFIG_ADDR))
            {
-             char *addrs = inet_ntoa(config->addr);
+             inet_ntop(AF_INET, &config->addr, daemon->addrbuff, ADDRSTRLEN);
              
              if ((ltmp = lease_find_by_addr(config->addr)) && 
                  ltmp != lease &&
@@ -1088,7 +1108,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                  unsigned char *mac = extended_hwaddr(ltmp->hwaddr_type, ltmp->hwaddr_len,
                                                       ltmp->hwaddr, ltmp->clid_len, ltmp->clid, &len);
                  my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is leased to %s"),
-                           addrs, print_mac(daemon->namebuff, mac, len));
+                           daemon->addrbuff, print_mac(daemon->namebuff, mac, len));
                }
              else
                {
@@ -1097,10 +1117,10 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                    if (context->router.s_addr == config->addr.s_addr)
                      break;
                  if (tmp)
-                   my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), addrs);
+                   my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), daemon->addrbuff);
                  else if (have_config(config, CONFIG_DECLINED) &&
                           difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
-                   my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
+                   my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), daemon->addrbuff);
                  else
                    conf = config->addr;
                }
@@ -1303,9 +1323,10 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                 a lease from one of it's MACs to give the address to another. */
              if (config && config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type))
                {
+                 inet_ntop(AF_INET, &ltmp->addr, daemon->addrbuff, ADDRSTRLEN);
                  my_syslog(MS_DHCP | LOG_INFO, _("abandoning lease to %s of %s"),
                            print_mac(daemon->namebuff, ltmp->hwaddr, ltmp->hwaddr_len), 
-                           inet_ntoa(ltmp->addr));
+                           daemon->addrbuff);
                  lease = ltmp;
                }
              else
@@ -1674,42 +1695,40 @@ static void add_extradata_opt(struct dhcp_lease *lease, unsigned char *opt)
 static void log_packet(char *type, void *addr, unsigned char *ext_mac, 
                       int mac_len, char *interface, char *string, char *err, u32 xid)
 {
-  struct in_addr a;
   if (!err && !option_bool(OPT_LOG_OPTS) && option_bool(OPT_QUIET_DHCP))
     return;
   
-  /* addr may be misaligned */
+  daemon->addrbuff[0] = 0;
   if (addr)
-    memcpy(&a, addr, sizeof(a));
+    inet_ntop(AF_INET, addr, daemon->addrbuff, ADDRSTRLEN);
   
   print_mac(daemon->namebuff, ext_mac, mac_len);
   
-  if(option_bool(OPT_LOG_OPTS))
-     my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s%s",
-              ntohl(xid), 
-              type,
-              interface, 
-              addr ? inet_ntoa(a) : "",
-              addr ? " " : "",
-              daemon->namebuff,
-              string ? string : "",
-              err ? err : "");
+  if (option_bool(OPT_LOG_OPTS))
+    my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s%s",
+             ntohl(xid), 
+             type,
+             interface, 
+             daemon->addrbuff,
+             addr ? " " : "",
+             daemon->namebuff,
+             string ? string : "",
+             err ? err : "");
   else
     my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s%s",
              type,
              interface, 
-             addr ? inet_ntoa(a) : "",
+             daemon->addrbuff,
              addr ? " " : "",
              daemon->namebuff,
              string ? string : "",
              err ? err : "");
-
+  
 #ifdef HAVE_UBUS
-       if (!strcmp(type, "DHCPACK"))
-               ubus_event_bcast("dhcp.ack", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface);
-       else if (!strcmp(type, "DHCPRELEASE"))
-               ubus_event_bcast("dhcp.release", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface);
+  if (!strcmp(type, "DHCPACK"))
+    ubus_event_bcast("dhcp.ack", daemon->namebuff, addr ? daemon->addrbuff : NULL, string, interface);
+  else if (!strcmp(type, "DHCPRELEASE"))
+    ubus_event_bcast("dhcp.release", daemon->namebuff, addr ? daemon->addrbuff : NULL, string, interface);
 #endif
 }
 
@@ -1861,7 +1880,10 @@ static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id
   if (option_bool(OPT_LOG_OPTS))
     {
       if (mess->siaddr.s_addr != 0)
-       my_syslog(MS_DHCP | LOG_INFO, _("%u next server: %s"), ntohl(mess->xid), inet_ntoa(mess->siaddr));
+       {
+         inet_ntop(AF_INET, &mess->siaddr, daemon->addrbuff, ADDRSTRLEN);
+         my_syslog(MS_DHCP | LOG_INFO, _("%u next server: %s"), ntohl(mess->xid), daemon->addrbuff);
+       }
       
       if ((mess->flags & htons(0x8000)) && mess->ciaddr.s_addr == 0)
        my_syslog(MS_DHCP | LOG_INFO, _("%u broadcast response"), ntohl(mess->xid));
@@ -2785,11 +2807,4 @@ static void apply_delay(u32 xid, time_t recvtime, struct dhcp_netid *netid)
     }
 }
 
-#endif
-  
-
-  
-  
-
-
-  
+#endif /* HAVE_DHCP */
index b3f0a0a..5c2ff97 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -919,11 +919,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
       
   
     case DHCP6RENEW:
+    case DHCP6REBIND:
       {
+       int address_assigned = 0;
+
        /* set reply message type */
        *outmsgtypep = DHCP6REPLY;
        
-       log6_quiet(state, "DHCPRENEW", NULL, NULL);
+       log6_quiet(state, msg_type == DHCP6RENEW ? "DHCPRENEW" : "DHCPREBIND", NULL, NULL);
 
        for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
          {
@@ -952,24 +955,35 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                                          state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, 
                                          state->iaid, &req_addr)))
                  {
-                   /* If the server cannot find a client entry for the IA the server
-                      returns the IA containing no addresses with a Status Code option set
-                      to NoBinding in the Reply message. */
-                   save_counter(iacntr);
-                   t1cntr = 0;
-                   
-                   log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
-                   
-                   o1 = new_opt6(OPTION6_STATUS_CODE);
-                   put_opt6_short(DHCP6NOBINDING);
-                   put_opt6_string(_("no binding found"));
-                   end_opt6(o1);
-
-                   preferred_time = valid_time = 0;
-                   break;
+                   if (msg_type == DHCP6REBIND)
+                     {
+                       /* When rebinding, we can create a lease if it doesn't exist. */
+                       lease = lease6_allocate(&req_addr, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA);
+                       if (lease)
+                         lease_set_iaid(lease, state->iaid);
+                       else
+                         break;
+                     }
+                   else
+                     {
+                       /* If the server cannot find a client entry for the IA the server
+                          returns the IA containing no addresses with a Status Code option set
+                          to NoBinding in the Reply message. */
+                       save_counter(iacntr);
+                       t1cntr = 0;
+                       
+                       log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
+                       
+                       o1 = new_opt6(OPTION6_STATUS_CODE);
+                       put_opt6_short(DHCP6NOBINDING);
+                       put_opt6_string(_("no binding found"));
+                       end_opt6(o1);
+                       
+                       preferred_time = valid_time = 0;
+                       break;
+                     }
                  }
                
-               
                if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) ||
                    (this_context = address6_valid(state->context, &req_addr, tagif, 1)))
                  {
@@ -1000,6 +1014,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                    
                    if (preferred_time == 0)
                      message = _("deprecated");
+
+                   address_assigned = 1;
                  }
                else
                  {
@@ -1022,10 +1038,18 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
            end_ia(t1cntr, min_time, 1);
            end_opt6(o);
          }
+
+       if (!address_assigned && msg_type == DHCP6REBIND)
+         { 
+           /* can't create lease for any address, return error */
+           o1 = new_opt6(OPTION6_STATUS_CODE);
+           put_opt6_short(DHCP6NOADDRS);
+           put_opt6_string(_("no addresses available"));
+           end_opt6(o1);
+         }
        
        tagif = add_options(state, 0);
        break;
-       
       }
       
     case DHCP6CONFIRM:
index 16e6b55..58c6d8f 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
index 4a3e01d..9b10063 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
index b34ea77..ccfe9ed 100644 (file)
@@ -98,7 +98,7 @@ int add_to_ipset(const char *setname, const union all_addr *ipaddr,
   io.pfrio_size = 1;
   if (ioctl(dev, DIOCRADDTABLES, &io))
     {
-      my_syslog(LOG_WARNING, _("IPset: error:%s"), pfr_strerror(errno));
+      my_syslog(LOG_WARNING, _("IPset: error: %s"), pfr_strerror(errno));
       
       return -1;
     }
index aa240e5..37bdff2 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@ static void handle_tftp(time_t now, struct tftp_transfer *transfer, ssize_t len)
 static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix);
 static void free_transfer(struct tftp_transfer *transfer);
 static ssize_t tftp_err(int err, char *packet, char *message, char *file);
-static ssize_t tftp_err_oops(char *packet, char *file);
+static ssize_t tftp_err_oops(char *packet, const char *file);
 static ssize_t get_block(char *packet, struct tftp_transfer *transfer);
 static char *next(char **p, char *end);
 static void sanitise(char *buf);
@@ -39,6 +39,7 @@ static void sanitise(char *buf);
 #define ERR_PERM   2
 #define ERR_FULL   3
 #define ERR_ILL    4
+#define ERR_TID    5
 
 void tftp_request(struct listener *listen, time_t now)
 {
@@ -94,7 +95,7 @@ void tftp_request(struct listener *listen, time_t now)
 
   if ((len = recvmsg(listen->tftpfd, &msg, 0)) < 2)
     return;
-
+  
   /* Can always get recvd interface for IPv6 */
   if (!check_dest)
     {
@@ -583,11 +584,27 @@ void check_tftp_listeners(time_t now)
     for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
       if (poll_check(transfer->sockfd, POLLIN))
        {
+         union mysockaddr peer;
+         socklen_t addr_len = sizeof(union mysockaddr);
+         ssize_t len;
+         
          /* we overwrote the buffer... */
          daemon->srv_save = NULL;
-         handle_tftp(now, transfer, recv(transfer->sockfd, daemon->packet, daemon->packet_buff_sz, 0));
-       }
 
+         if ((len = recvfrom(transfer->sockfd, daemon->packet, daemon->packet_buff_sz, 0, &peer.sa, &addr_len)) > 0)
+           {
+             if (sockaddr_isequal(&peer, &transfer->peer)) 
+               handle_tftp(now, transfer, len);
+             else
+               {
+                 /* Wrong source address. See rfc1350 para 4. */
+                 prettyprint_addr(&peer, daemon->addrbuff);
+                 len = tftp_err(ERR_TID, daemon->packet, _("ignoring packet from %s (TID mismatch)"), daemon->addrbuff);
+                 sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer));
+               }
+           }
+       }
+         
   for (transfer = daemon->tftp_trans, up = &daemon->tftp_trans; transfer; transfer = tmp)
     {
       tmp = transfer->next;
@@ -602,7 +619,7 @@ void check_tftp_listeners(time_t now)
                  
          /* we overwrote the buffer... */
          daemon->srv_save = NULL;
-        
+
          if ((len = get_block(daemon->packet, transfer)) == -1)
            {
              len = tftp_err_oops(daemon->packet, transfer->file->filename);
@@ -736,22 +753,25 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file)
   char *errstr = strerror(errno);
   
   memset(packet, 0, daemon->packet_buff_sz);
-  sanitise(file);
+  if (file)
+    sanitise(file);
   
   mess->op = htons(OP_ERR);
   mess->err = htons(err);
   len = snprintf(mess->message, MAXMESSAGE,  message, file, errstr);
   ret += (len < MAXMESSAGE) ? len + 1 : MAXMESSAGE; /* include terminating zero */
   
-  my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message);
+  if (err != ERR_FNF || !option_bool(OPT_QUIET_TFTP))
+    my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message);
   
   return  ret;
 }
 
-static ssize_t tftp_err_oops(char *packet, char *file)
+static ssize_t tftp_err_oops(char *packet, const char *file)
 {
   /* May have >1 refs to file, so potentially mangle a copy of the name */
-  strcpy(daemon->namebuff, file);
+  if (file != daemon->namebuff)
+    strcpy(daemon->namebuff, file);
   return tftp_err(ERR_NOTDEF, packet, _("cannot read %s: %s"), daemon->namebuff);
 }
 
index 5f81287..0c502ad 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include <libubus.h>
 
 static struct blob_buf b;
-static int notify;
 static int error_logged = 0;
 
 static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
                               struct ubus_request_data *req, const char *method,
                               struct blob_attr *msg);
 
+#ifdef HAVE_CONNTRACK
+enum {
+  SET_CONNMARK_ALLOWLIST_MARK,
+  SET_CONNMARK_ALLOWLIST_MASK,
+  SET_CONNMARK_ALLOWLIST_PATTERNS
+};
+static const struct blobmsg_policy set_connmark_allowlist_policy[] = {
+  [SET_CONNMARK_ALLOWLIST_MARK] = {
+    .name = "mark",
+    .type = BLOBMSG_TYPE_INT32
+  },
+  [SET_CONNMARK_ALLOWLIST_MASK] = {
+    .name = "mask",
+    .type = BLOBMSG_TYPE_INT32
+  },
+  [SET_CONNMARK_ALLOWLIST_PATTERNS] = {
+    .name = "patterns",
+    .type = BLOBMSG_TYPE_ARRAY
+  }
+};
+static int ubus_handle_set_connmark_allowlist(struct ubus_context *ctx, struct ubus_object *obj,
+                                             struct ubus_request_data *req, const char *method,
+                                             struct blob_attr *msg);
+#endif
+
 static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj);
 
 static const struct ubus_method ubus_object_methods[] = {
   UBUS_METHOD_NOARG("metrics", ubus_handle_metrics),
+#ifdef HAVE_CONNTRACK
+  UBUS_METHOD("set_connmark_allowlist", ubus_handle_set_connmark_allowlist, set_connmark_allowlist_policy),
+#endif
 };
 
 static struct ubus_object_type ubus_object_type =
@@ -50,17 +77,16 @@ static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
   (void)ctx;
 
   my_syslog(LOG_DEBUG, _("UBus subscription callback: %s subscriber(s)"), obj->has_subscribers ? "1" : "0");
-  notify = obj->has_subscribers;
 }
 
 static void ubus_destroy(struct ubus_context *ubus)
 {
-  // Forces re-initialization when we're reusing the same definitions later on.
-  ubus_object.id = 0;
-  ubus_object_type.id = 0;
-
   ubus_free(ubus);
   daemon->ubus = NULL;
+  
+  /* Forces re-initialization when we're reusing the same definitions later on. */
+  ubus_object.id = 0;
+  ubus_object_type.id = 0;
 }
 
 static void ubus_disconnect_cb(struct ubus_context *ubus)
@@ -76,42 +102,27 @@ static void ubus_disconnect_cb(struct ubus_context *ubus)
     }
 }
 
-void ubus_init()
+char *ubus_init()
 {
   struct ubus_context *ubus = NULL;
   int ret = 0;
 
-  ubus = ubus_connect(NULL);
-  if (!ubus)
-    {
-      if (!error_logged)
-        {
-          my_syslog(LOG_ERR, _("Cannot initialize UBus: connection failed"));
-          error_logged = 1;
-        }
-
-      ubus_destroy(ubus);
-      return;
-    }
-
+  if (!(ubus = ubus_connect(NULL)))
+    return NULL;
+  
   ubus_object.name = daemon->ubus_name;
   ret = ubus_add_object(ubus, &ubus_object);
   if (ret)
     {
-      if (!error_logged)
-        {
-          my_syslog(LOG_ERR, _("Cannot add object to UBus: %s"), ubus_strerror(ret));
-          error_logged = 1;
-        }
       ubus_destroy(ubus);
-      return;
-    }
-
+      return (char *)ubus_strerror(ret);
+    }    
+  
   ubus->connection_lost = ubus_disconnect_cb;
   daemon->ubus = ubus;
   error_logged = 0;
 
-  my_syslog(LOG_INFO, _("Connected to system UBus"));
+  return NULL;
 }
 
 void set_ubus_listeners()
@@ -160,6 +171,16 @@ void check_ubus_listeners()
     }
 }
 
+#define CHECK(stmt) \
+  do { \
+    int e = (stmt); \
+    if (e) \
+      { \
+       my_syslog(LOG_ERR, _("UBus command failed: %d (%s)"), e, #stmt); \
+       return (UBUS_STATUS_UNKNOWN_ERROR); \
+      } \
+  } while (0)
+
 static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
                               struct ubus_request_data *req, const char *method,
                               struct blob_attr *msg)
@@ -170,36 +191,196 @@ static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj
   (void)method;
   (void)msg;
 
-  blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
+  CHECK(blob_buf_init(&b, BLOBMSG_TYPE_TABLE));
 
   for (i=0; i < __METRIC_MAX; i++)
-    blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]);
+    CHECK(blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]));
   
-  return ubus_send_reply(ctx, req, b.head);
+  CHECK(ubus_send_reply(ctx, req, b.head));
+  return UBUS_STATUS_OK;
 }
 
+#ifdef HAVE_CONNTRACK
+static int ubus_handle_set_connmark_allowlist(struct ubus_context *ctx, struct ubus_object *obj,
+                                             struct ubus_request_data *req, const char *method,
+                                             struct blob_attr *msg)
+{
+  const struct blobmsg_policy *policy = set_connmark_allowlist_policy;
+  size_t policy_len = countof(set_connmark_allowlist_policy);
+  struct allowlist *allowlists = NULL, **allowlists_pos;
+  char **patterns = NULL, **patterns_pos;
+  u32 mark, mask = UINT32_MAX;
+  size_t num_patterns = 0;
+  struct blob_attr *tb[policy_len];
+  struct blob_attr *attr;
+  
+  if (blobmsg_parse(policy, policy_len, tb, blob_data(msg), blob_len(msg)))
+    return UBUS_STATUS_INVALID_ARGUMENT;
+  
+  if (!tb[SET_CONNMARK_ALLOWLIST_MARK])
+    return UBUS_STATUS_INVALID_ARGUMENT;
+  mark = blobmsg_get_u32(tb[SET_CONNMARK_ALLOWLIST_MARK]);
+  if (!mark)
+    return UBUS_STATUS_INVALID_ARGUMENT;
+  
+  if (tb[SET_CONNMARK_ALLOWLIST_MASK])
+    {
+      mask = blobmsg_get_u32(tb[SET_CONNMARK_ALLOWLIST_MASK]);
+      if (!mask || (mark & ~mask))
+       return UBUS_STATUS_INVALID_ARGUMENT;
+    }
+  
+  if (tb[SET_CONNMARK_ALLOWLIST_PATTERNS])
+    {
+      struct blob_attr *head = blobmsg_data(tb[SET_CONNMARK_ALLOWLIST_PATTERNS]);
+      size_t len = blobmsg_data_len(tb[SET_CONNMARK_ALLOWLIST_PATTERNS]);
+      __blob_for_each_attr(attr, head, len)
+       {
+         char *pattern;
+         if (blob_id(attr) != BLOBMSG_TYPE_STRING)
+           return UBUS_STATUS_INVALID_ARGUMENT;
+         if (!(pattern = blobmsg_get_string(attr)))
+           return UBUS_STATUS_INVALID_ARGUMENT;
+         if (strcmp(pattern, "*") && !is_valid_dns_name_pattern(pattern))
+           return UBUS_STATUS_INVALID_ARGUMENT;
+         num_patterns++;
+       }
+    }
+  
+  for (allowlists_pos = &daemon->allowlists; *allowlists_pos; allowlists_pos = &(*allowlists_pos)->next)
+    if ((*allowlists_pos)->mark == mark && (*allowlists_pos)->mask == mask)
+      {
+       struct allowlist *allowlists_next = (*allowlists_pos)->next;
+       for (patterns_pos = (*allowlists_pos)->patterns; *patterns_pos; patterns_pos++)
+         {
+           free(*patterns_pos);
+           *patterns_pos = NULL;
+         }
+       free((*allowlists_pos)->patterns);
+       (*allowlists_pos)->patterns = NULL;
+       free(*allowlists_pos);
+       *allowlists_pos = allowlists_next;
+       break;
+      }
+  
+  if (!num_patterns)
+    return UBUS_STATUS_OK;
+  
+  patterns = whine_malloc((num_patterns + 1) * sizeof(char *));
+  if (!patterns)
+    goto fail;
+  patterns_pos = patterns;
+  if (tb[SET_CONNMARK_ALLOWLIST_PATTERNS])
+    {
+      struct blob_attr *head = blobmsg_data(tb[SET_CONNMARK_ALLOWLIST_PATTERNS]);
+      size_t len = blobmsg_data_len(tb[SET_CONNMARK_ALLOWLIST_PATTERNS]);
+      __blob_for_each_attr(attr, head, len)
+       {
+         char *pattern;
+         if (!(pattern = blobmsg_get_string(attr)))
+           goto fail;
+         if (!(*patterns_pos = whine_malloc(strlen(pattern) + 1)))
+           goto fail;
+         strcpy(*patterns_pos++, pattern);
+       }
+    }
+  
+  allowlists = whine_malloc(sizeof(struct allowlist));
+  if (!allowlists)
+    goto fail;
+  memset(allowlists, 0, sizeof(struct allowlist));
+  allowlists->mark = mark;
+  allowlists->mask = mask;
+  allowlists->patterns = patterns;
+  allowlists->next = daemon->allowlists;
+  daemon->allowlists = allowlists;
+  return UBUS_STATUS_OK;
+  
+fail:
+  if (patterns)
+    {
+      for (patterns_pos = patterns; *patterns_pos; patterns_pos++)
+       {
+         free(*patterns_pos);
+         *patterns_pos = NULL;
+       }
+      free(patterns);
+      patterns = NULL;
+    }
+  if (allowlists)
+    {
+      free(allowlists);
+      allowlists = NULL;
+    }
+  return UBUS_STATUS_UNKNOWN_ERROR;
+}
+#endif
+
+#undef CHECK
+
+#define CHECK(stmt) \
+  do { \
+    int e = (stmt); \
+    if (e) \
+      { \
+       my_syslog(LOG_ERR, _("UBus command failed: %d (%s)"), e, #stmt); \
+       return; \
+      } \
+  } while (0)
+
 void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
 {
   struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
-  int ret;
 
-  if (!ubus || !notify)
+  if (!ubus || !ubus_object.has_subscribers)
     return;
 
-  blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
+  CHECK(blob_buf_init(&b, BLOBMSG_TYPE_TABLE));
   if (mac)
-    blobmsg_add_string(&b, "mac", mac);
+    CHECK(blobmsg_add_string(&b, "mac", mac));
   if (ip)
-    blobmsg_add_string(&b, "ip", ip);
+    CHECK(blobmsg_add_string(&b, "ip", ip));
   if (name)
-    blobmsg_add_string(&b, "name", name);
+    CHECK(blobmsg_add_string(&b, "name", name));
   if (interface)
-    blobmsg_add_string(&b, "interface", interface);
+    CHECK(blobmsg_add_string(&b, "interface", interface));
+  
+  CHECK(ubus_notify(ubus, &ubus_object, type, b.head, -1));
+}
+
+#ifdef HAVE_CONNTRACK
+void ubus_event_bcast_connmark_allowlist_refused(u32 mark, const char *name)
+{
+  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
+
+  if (!ubus || !ubus_object.has_subscribers)
+    return;
+
+  CHECK(blob_buf_init(&b, 0));
+  CHECK(blobmsg_add_u32(&b, "mark", mark));
+  CHECK(blobmsg_add_string(&b, "name", name));
+  
+  CHECK(ubus_notify(ubus, &ubus_object, "connmark-allowlist.refused", b.head, -1));
+}
+
+void ubus_event_bcast_connmark_allowlist_resolved(u32 mark, const char *name, const char *value, u32 ttl)
+{
+  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
+
+  if (!ubus || !ubus_object.has_subscribers)
+    return;
+
+  CHECK(blob_buf_init(&b, 0));
+  CHECK(blobmsg_add_u32(&b, "mark", mark));
+  CHECK(blobmsg_add_string(&b, "name", name));
+  CHECK(blobmsg_add_string(&b, "value", value));
+  CHECK(blobmsg_add_u32(&b, "ttl", ttl));
   
-  ret = ubus_notify(ubus, &ubus_object, type, b.head, -1);
-  if (!ret)
-    my_syslog(LOG_ERR, _("Failed to send UBus event: %s"), ubus_strerror(ret));
+  /* Set timeout to allow UBus subscriber to configure firewall rules before returning. */
+  CHECK(ubus_notify(ubus, &ubus_object, "connmark-allowlist.resolved", b.head, /* timeout: */ 1000));
 }
+#endif
 
+#undef CHECK
 
 #endif /* HAVE_UBUS */
index 5f13027..1425764 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -316,7 +316,7 @@ void *whine_malloc(size_t size)
   return ret;
 }
 
-int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2)
+int sockaddr_isequal(const union mysockaddr *s1, const union mysockaddr *s2)
 {
   if (s1->sa.sa_family == s2->sa.sa_family)
     { 
@@ -436,7 +436,17 @@ int netmask_length(struct in_addr mask)
 int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
 {
   return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
-} 
+}
+
+int is_same_net_prefix(struct in_addr a, struct in_addr b, int prefix)
+{
+  struct in_addr mask;
+
+  mask.s_addr = htonl(~((1 << (32 - prefix)) - 1));
+
+  return is_same_net(a, b, mask);
+}
+
 
 int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen)
 {