mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-04 13:48:30 +00:00
Compare commits
22
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbc5205702 | ||
|
|
cbc6524234 | ||
|
|
094b5c3d90 | ||
|
|
3267804598 | ||
|
|
476693678e | ||
|
|
bd9520b7ad | ||
|
|
3ad3f3bbd4 | ||
|
|
ad946d555d | ||
|
|
800c5cc1e7 | ||
|
|
857973e6f7 | ||
|
|
9c448c8018 | ||
|
|
193de4abf5 | ||
|
|
98906275a0 | ||
|
|
b9ff5c8f43 | ||
|
|
3d9d2dd001 | ||
|
|
17b475912f | ||
|
|
e9828b6f66 | ||
|
|
72eba2bffc | ||
|
|
6ac3bc0452 | ||
|
|
00cd9d5519 | ||
|
|
f2658275b2 | ||
|
|
25e27235dd |
No files matched your search
@@ -1,3 +1,29 @@
|
||||
version 2.73
|
||||
Fix crash at startup when an empty suffix is supplied to
|
||||
--conf-dir, also trivial memory leak. Thanks to
|
||||
Tomas Hozza for spotting this.
|
||||
|
||||
Remove floor of 4096 on advertised EDNS0 packet size when
|
||||
DNSSEC in use, the original rationale for this has long gone.
|
||||
Thanks to Anders Kaseorg for spotting this.
|
||||
|
||||
Use inotify for checking on updates to /etc/resolv.conf and
|
||||
friends under Linux. This fixes race conditions when the files are
|
||||
updated rapidly and saves CPU by noy polling.
|
||||
|
||||
Fix breakage of --domain=<domain>,<subnet>,local - only reverse
|
||||
queries were intercepted. THis appears to have been broken
|
||||
since 2.69. Thanks to Josh Stone for finding the bug.
|
||||
|
||||
Eliminate IPv6 privacy addresses and deprecated addresses from
|
||||
the answers given by --interface-name. Note that reverse queries
|
||||
(ie looking for names, given addresses) are not affected.
|
||||
Thanks to Michael Gorbach for the suggestion.
|
||||
|
||||
Fix crash in DNSSEC code with long RRs. Thanks to Marco Davids
|
||||
for the bug report.
|
||||
|
||||
|
||||
version 2.72
|
||||
Add ra-advrouter mode, for RFC-3775 mobile IPv6 support.
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ 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 \
|
||||
domain.o dnssec.o blockdata.o tables.o loop.o
|
||||
domain.o dnssec.o blockdata.o tables.o loop.o inotify.o
|
||||
|
||||
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
|
||||
dns-protocol.h radv-protocol.h ip6addr.h
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
|
||||
dhcp6.c rfc3315.c dhcp-common.c outpacket.c \
|
||||
radv.c slaac.c auth.c ipset.c domain.c \
|
||||
dnssec.c dnssec-openssl.c blockdata.c tables.c \
|
||||
loop.c
|
||||
loop.c inotify.c
|
||||
|
||||
LOCAL_MODULE := dnsmasq
|
||||
|
||||
|
||||
Vendored
+14
@@ -1,3 +1,17 @@
|
||||
dnsmasq (2.73-1) unstable; urgency=low
|
||||
|
||||
* New upstream.
|
||||
* Tweak field width in cache dump to avoid truncating IPv6
|
||||
addresses. (closes: #771557)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Fri, 03 Oct 2014 08:49:42 +0000
|
||||
|
||||
dnsmasq (2.72-2) unstable; urgency=low
|
||||
|
||||
* Fix build in Debian-kFreeBSD. (closes: #763693)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Thu, 02 Oct 2014 22:34:12 +0000
|
||||
|
||||
dnsmasq (2.72-1) unstable; urgency=low
|
||||
|
||||
* New upstream.
|
||||
|
||||
Vendored
+1
-1
@@ -3,7 +3,7 @@ Section: net
|
||||
Priority: optional
|
||||
Build-depends: gettext, libnetfilter-conntrack-dev [linux-any],
|
||||
libidn11-dev, libdbus-1-dev (>=0.61), libgmp-dev,
|
||||
nettle-dev (>=2.4-3)
|
||||
nettle-dev (>=2.4-3), libbsd-dev [!linux-any]
|
||||
Maintainer: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Standards-Version: 3.9.5
|
||||
|
||||
|
||||
Vendored
+8
-3
@@ -23,7 +23,7 @@ DEB_COPTS = $(COPTS)
|
||||
|
||||
TARGET = install-i18n
|
||||
|
||||
DEB_BUILD_ARCH_OS := $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS)
|
||||
DEB_HOST_ARCH_OS := $(shell dpkg-architecture -qDEB_HOST_ARCH_OS)
|
||||
|
||||
# Force package version based on git tags.
|
||||
ifneq (,$(filter gitversion,$(DEB_BUILD_OPTIONS)))
|
||||
@@ -35,7 +35,7 @@ ifeq (,$(filter nodbus,$(DEB_BUILD_OPTIONS)))
|
||||
endif
|
||||
|
||||
ifeq (,$(filter noconntrack,$(DEB_BUILD_OPTIONS)))
|
||||
ifeq ($(DEB_BUILD_ARCH_OS),linux)
|
||||
ifeq ($(DEB_HOST_ARCH_OS),linux)
|
||||
DEB_COPTS += -DHAVE_CONNTRACK
|
||||
endif
|
||||
endif
|
||||
@@ -83,6 +83,11 @@ ifeq (,$(filter nodnssec,$(DEB_BUILD_OPTIONS)))
|
||||
DEB_COPTS += -DHAVE_DNSSEC
|
||||
endif
|
||||
|
||||
ifneq ($(DEB_HOST_ARCH_OS),linux)
|
||||
# For strlcpy in FreeBSD
|
||||
LDFLAGS += -lbsd
|
||||
endif
|
||||
|
||||
clean:
|
||||
$(checkdir)
|
||||
rm -rf debian/daemon debian/base debian/utils debian/*~ debian/files debian/substvars debian/utils-substvars
|
||||
@@ -171,7 +176,7 @@ endif
|
||||
chmod -R g-ws debian/base
|
||||
dpkg --build debian/base ..
|
||||
|
||||
ifeq ($(DEB_BUILD_ARCH_OS),linux)
|
||||
ifeq ($(DEB_HOST_ARCH_OS),linux)
|
||||
rm -rf debian/utils
|
||||
install -m 755 -d debian/utils/DEBIAN \
|
||||
-d debian/utils/usr/share/man/man1 \
|
||||
|
||||
@@ -645,4 +645,4 @@
|
||||
#conf-dir=/etc/dnsmasq.d,.bak
|
||||
|
||||
# Include all files in a directory which end in .conf
|
||||
#conf-dir=/etc/dnsmasq.d/*.conf
|
||||
#conf-dir=/etc/dnsmasq.d/,*.conf
|
||||
@@ -10,7 +10,7 @@ msgstr ""
|
||||
"Project-Id-Version: pl\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-06-10 20:57+0100\n"
|
||||
"PO-Revision-Date: 2013-12-04 01:34+0100\n"
|
||||
"PO-Revision-Date: 2014-09-23 12:45+0100\n"
|
||||
"Last-Translator: Jan Psota <jasiupsota@gmail.com>\n"
|
||||
"Language-Team: polski <>\n"
|
||||
"Language: pl\n"
|
||||
@@ -18,12 +18,12 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
|
||||
"X-Generator: Poedit 1.5.5\n"
|
||||
"X-Generator: Poedit 1.6.9\n"
|
||||
"X-Language: pl_PL\n"
|
||||
|
||||
#: cache.c:505
|
||||
msgid "Internal error in cache."
|
||||
msgstr ""
|
||||
msgstr "Wewnętrzny błąd w pamięci podręcznej."
|
||||
|
||||
#: cache.c:908
|
||||
#, c-format
|
||||
@@ -304,18 +304,16 @@ msgid "Specify path to resolv.conf (defaults to %s)."
|
||||
msgstr "Wskazanie położenia pliku resolv.conf (domyślnie: %s)."
|
||||
|
||||
#: option.c:362
|
||||
#, fuzzy
|
||||
msgid "Specify path to file with server= options"
|
||||
msgstr "Określenie ścieżki do pliku PID (domyślnie: %s)."
|
||||
msgstr "Wskazanie położenia pliku z opcjami server="
|
||||
|
||||
#: option.c:363
|
||||
msgid "Specify address(es) of upstream servers with optional domains."
|
||||
msgstr "Wskazywanie adresów serwerów nazw, opcjonalnie z przypisaniem do domeny."
|
||||
|
||||
#: option.c:364
|
||||
#, fuzzy
|
||||
msgid "Specify address of upstream servers for reverse address queries"
|
||||
msgstr "Wskazywanie adresów serwerów nazw, opcjonalnie z przypisaniem do domeny."
|
||||
msgstr "Wskazanie serwerów nazw do odwrotnej translacji adresów."
|
||||
|
||||
#: option.c:365
|
||||
msgid "Never forward queries to specified domains."
|
||||
@@ -650,23 +648,23 @@ msgstr "Wskazanie domeny i zakresu adresów dla generowanych nazw"
|
||||
|
||||
#: option.c:446
|
||||
msgid "Activate DNSSEC validation"
|
||||
msgstr ""
|
||||
msgstr "Uaktywnienie walidacji DNSSEC"
|
||||
|
||||
#: option.c:447
|
||||
msgid "Specify trust anchor key digest."
|
||||
msgstr ""
|
||||
msgstr "Wskazanie punktu zaufania dla uwierzytelniania DNSSEC."
|
||||
|
||||
#: option.c:448
|
||||
msgid "Disable upstream checking for DNSSEC debugging."
|
||||
msgstr ""
|
||||
msgstr "Akceptowanie nieuwiarygodnionych odpowiedzi DNSSEC (ustawienie bitu CD w zapytaniach)."
|
||||
|
||||
#: option.c:449
|
||||
msgid "Ensure answers without DNSSEC are in unsigned zones."
|
||||
msgstr ""
|
||||
msgstr "Upewnianie się, że odpowiedzi bez DNSSEC pochodzą ze stref niepodpisanych."
|
||||
|
||||
#: option.c:450
|
||||
msgid "Don't check DNSSEC signature timestamps until first cache-reload"
|
||||
msgstr ""
|
||||
msgstr "Wyłączenie sprawdzania sygnatur czasowych DNSSEC do pierwszego przeładowania pamięci podręcznej."
|
||||
|
||||
#: option.c:452
|
||||
msgid "Specify DHCPv6 prefix class"
|
||||
@@ -690,11 +688,11 @@ msgstr "Wyłączenie logowania RA."
|
||||
|
||||
#: option.c:458
|
||||
msgid "Accept queries only from directly-connected networks"
|
||||
msgstr ""
|
||||
msgstr "Akceptowanie zapytań wyłącznie z sieci podpiętych bezpośrednio."
|
||||
|
||||
#: option.c:459
|
||||
msgid "Detect and remove DNS forwarding loops"
|
||||
msgstr ""
|
||||
msgstr "Wykrywanie i usuwanie pętli zapytań DNS."
|
||||
|
||||
#: option.c:661
|
||||
#, c-format
|
||||
@@ -951,18 +949,16 @@ msgid "Bad name in host-record"
|
||||
msgstr "niedopuszczalna nazwa w host-record"
|
||||
|
||||
#: option.c:3826
|
||||
#, fuzzy
|
||||
msgid "bad trust anchor"
|
||||
msgstr "nieprawidłowy zakres numerów portów"
|
||||
msgstr "nieprawidłowa specyfikacja punktu zaufania"
|
||||
|
||||
#: option.c:3840
|
||||
msgid "bad HEX in trust anchor"
|
||||
msgstr ""
|
||||
msgstr "zły zapis szesnastkowy"
|
||||
|
||||
#: option.c:3850
|
||||
#, fuzzy
|
||||
msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
|
||||
msgstr "nieobsługiwana opcja (sprawdź, czy obsługa DHCP/TFTP/DBus została wkompilowana)"
|
||||
msgstr "nieobsługiwana opcja (sprawdź, czy obsługa DHCP/TFTP/DNSSEC/DBus została wkompilowana)"
|
||||
|
||||
#: option.c:3909
|
||||
msgid "missing \""
|
||||
@@ -981,9 +977,8 @@ msgid "missing parameter"
|
||||
msgstr "brak parametru"
|
||||
|
||||
#: option.c:3972
|
||||
#, fuzzy
|
||||
msgid "illegal option"
|
||||
msgstr "nieprawidłowa opcja"
|
||||
msgstr "niedopuszczalna opcja"
|
||||
|
||||
#: option.c:3979
|
||||
msgid "error"
|
||||
@@ -1102,7 +1097,7 @@ msgstr "prawdopodobnie wykryto atak DNS-rebind: %s"
|
||||
|
||||
#: forward.c:1132 forward.c:1663
|
||||
msgid "Ignoring query from non-local network"
|
||||
msgstr ""
|
||||
msgstr "Ignorowanie zapytań z sieci pozalokalnych."
|
||||
|
||||
#: forward.c:2101
|
||||
#, c-format
|
||||
@@ -1180,9 +1175,9 @@ msgid "using nameserver %s#%d for %s %s"
|
||||
msgstr "używam serwera nazw %s#%d dla %s %s"
|
||||
|
||||
#: network.c:1483
|
||||
#, fuzzy, c-format
|
||||
#, c-format
|
||||
msgid "NOT using nameserver %s#%d - query loop detected"
|
||||
msgstr "używam serwera nazw %s#%d dla %s %s"
|
||||
msgstr "NIE używam serwera nazw %s#%d - wykryto pętlę zapytań"
|
||||
|
||||
#: network.c:1486
|
||||
#, c-format
|
||||
@@ -1196,16 +1191,15 @@ msgstr "używam serwera nazw %s#%d"
|
||||
|
||||
#: dnsmasq.c:154
|
||||
msgid "No trust anchors provided for DNSSEC"
|
||||
msgstr ""
|
||||
msgstr "Nie wskazano punktów zaufania dla DNSSEC."
|
||||
|
||||
#: dnsmasq.c:157
|
||||
msgid "Cannot reduce cache size from default when DNSSEC enabled"
|
||||
msgstr ""
|
||||
msgstr "Brak możliwości zmniejszenia pamięci podręcznej poniżej wielkości domyślnej w przypadku używania DNSSEC."
|
||||
|
||||
#: dnsmasq.c:159
|
||||
#, fuzzy
|
||||
msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
|
||||
msgstr "Obsługa DBus nie została wkompilowana -- ustaw HAVE_DBUS w src/config.h"
|
||||
msgstr "obsługa DNSSEC niedostępna - ustaw HAVE_DNSSEC w src/config.h"
|
||||
|
||||
#: dnsmasq.c:165
|
||||
msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
|
||||
@@ -1232,9 +1226,8 @@ 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:193
|
||||
#, fuzzy
|
||||
msgid "Loop detection not available: set HAVE_LOOP in src/config.h"
|
||||
msgstr "Serwer TFTP nie został wkompilowany -- ustaw HAVE_TFTP w src/config.h"
|
||||
msgstr "Wykrywanie pętli zapytań nie zostało wkompilowane - ustaw HAVE_LOOP w src/config.h"
|
||||
|
||||
#: dnsmasq.c:201
|
||||
msgid "zone serial must be configured in --auth-soa"
|
||||
@@ -1307,15 +1300,15 @@ msgstr "obsługa DBus włączona, trwa podłączanie do serwera DBus"
|
||||
|
||||
#: dnsmasq.c:672
|
||||
msgid "DNS service limited to local subnets"
|
||||
msgstr ""
|
||||
msgstr "usługa DNS ograniczona do lokalnych podsieci"
|
||||
|
||||
#: dnsmasq.c:677
|
||||
msgid "DNSSEC validation enabled"
|
||||
msgstr ""
|
||||
msgstr "walidacja DNSSEC włączona"
|
||||
|
||||
#: dnsmasq.c:679
|
||||
msgid "DNSSEC signature timestamps not checked until first cache reload"
|
||||
msgstr ""
|
||||
msgstr "sprawdzanie sygnatur czasowych DNSSEC wyłączone do czasu przeładowania pamięci podręcznej"
|
||||
|
||||
#: dnsmasq.c:684
|
||||
#, c-format
|
||||
@@ -1421,7 +1414,7 @@ msgstr "katalog TFTP %s nie jest dostępny: %s"
|
||||
|
||||
#: dnsmasq.c:1151
|
||||
msgid "now checking DNSSEC signature timestamps"
|
||||
msgstr ""
|
||||
msgstr "trwa sprawdzanie sygnatur czasowych podpisów DNSSEC"
|
||||
|
||||
#: dnsmasq.c:1218
|
||||
#, c-format
|
||||
@@ -1495,7 +1488,7 @@ msgstr "żądanie DHCP odebrano na interfejsie %s, który nie ma adresu"
|
||||
#: dhcp.c:408
|
||||
#, c-format
|
||||
msgid "ARP-cache injection failed: %s"
|
||||
msgstr ""
|
||||
msgstr "uzupełnienie pamięci podręcznej ARP nie powiodło się: %s"
|
||||
|
||||
#: dhcp.c:506
|
||||
#, c-format
|
||||
@@ -1746,13 +1739,13 @@ msgid "DHCP request for unsupported hardware type (%d) received on %s"
|
||||
msgstr "żądanie DHCP od urządzenia nieobsługiwanego typu (%d) odebrano na %s"
|
||||
|
||||
#: bpf.c:376
|
||||
#, fuzzy, c-format
|
||||
#, c-format
|
||||
msgid "cannot create PF_ROUTE socket: %s"
|
||||
msgstr "nie udało się utworzyć gniazda dla DHCP: %s"
|
||||
msgstr "nie udało się utworzyć gniazda PF_ROUTE: %s"
|
||||
|
||||
#: bpf.c:397
|
||||
msgid "Unknown protocol version from route socket"
|
||||
msgstr ""
|
||||
msgstr "Nieznana wersja protokołu."
|
||||
|
||||
#: helper.c:153
|
||||
msgid "lease() function missing in Lua script"
|
||||
@@ -1937,7 +1930,7 @@ msgstr ", przestarzały prefiks"
|
||||
#: dhcp-common.c:826
|
||||
#, c-format
|
||||
msgid ", lease time "
|
||||
msgstr ", czas dzierżawy"
|
||||
msgstr ", czas dzierżawy "
|
||||
|
||||
#: dhcp-common.c:868
|
||||
#, c-format
|
||||
@@ -2002,50 +1995,50 @@ msgstr "nie powiodło się otwieranie gniazda sterującego IPset: %s"
|
||||
#: blockdata.c:58
|
||||
#, c-format
|
||||
msgid "DNSSEC memory in use %u, max %u, allocated %u"
|
||||
msgstr ""
|
||||
msgstr "DNSSEC: zużycie pamięci %u, maks. %u, przydzielona %u"
|
||||
|
||||
#: tables.c:76
|
||||
msgid "error: fill_addr missused"
|
||||
msgstr ""
|
||||
msgstr "błąd: niepoprawnie użyty fill_addr"
|
||||
|
||||
#: tables.c:105
|
||||
#, fuzzy, c-format
|
||||
#, c-format
|
||||
msgid "failed to access pf devices: %s"
|
||||
msgstr "brak dostępu do %s: %s"
|
||||
msgstr "brak dostępu do /dev/pf (filtra pakietów): %s"
|
||||
|
||||
#: tables.c:119
|
||||
#, fuzzy, c-format
|
||||
#, c-format
|
||||
msgid "warning: no opened pf devices %s"
|
||||
msgstr "uwaga: nie znaleziono adresu interfejsu %s"
|
||||
msgstr "uwaga: brak otwartych filtrów pakietów %s"
|
||||
|
||||
#: tables.c:127
|
||||
#, fuzzy, c-format
|
||||
#, c-format
|
||||
msgid "error: cannot use table name %s"
|
||||
msgstr "nie można pobrać nazwy hosta: %s"
|
||||
msgstr "błąd: nie potrafię użyć nazwy tablicy %s"
|
||||
|
||||
#: tables.c:135
|
||||
#, c-format
|
||||
msgid "error: cannot strlcpy table name %s"
|
||||
msgstr ""
|
||||
msgstr "błąd: nie potrafię strlcpy nazwy tablicy %s"
|
||||
|
||||
#: tables.c:141
|
||||
#, c-format
|
||||
msgid "warning: pfr_add_tables: %s(%d)"
|
||||
msgstr ""
|
||||
msgstr "uwaga: pfr_add_tables: %s(%d)"
|
||||
|
||||
#: tables.c:147
|
||||
msgid "info: table created"
|
||||
msgstr ""
|
||||
msgstr "info: tablica utworzona"
|
||||
|
||||
#: tables.c:158
|
||||
#, c-format
|
||||
msgid "warning: DIOCR%sADDRS: %s"
|
||||
msgstr ""
|
||||
msgstr "uwaga: DIOCR%sADDRS: %s"
|
||||
|
||||
#: tables.c:162
|
||||
#, fuzzy, c-format
|
||||
#, c-format
|
||||
msgid "%d addresses %s"
|
||||
msgstr "zły adres"
|
||||
msgstr "%d adresów %s"
|
||||
|
||||
#~ msgid "Always send frequent router-advertisements"
|
||||
#~ msgstr "Rozsyłanie wielokrotne anonsów rutera (RA)"
|
||||
|
||||
@@ -363,6 +363,10 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == qtype &&
|
||||
(local_query || filter_zone(zone, flag, &addrlist->addr)))
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
if (addrlist->flags & ADDRLIST_REVONLY)
|
||||
continue;
|
||||
#endif
|
||||
found = 1;
|
||||
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
|
||||
+27
-11
@@ -322,7 +322,7 @@ static int is_expired(time_t now, struct crec *crecp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
|
||||
static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
|
||||
{
|
||||
/* Scan and remove old entries.
|
||||
If (flags & F_FORWARD) then remove any forward entries for name and any expired
|
||||
@@ -331,8 +331,8 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
||||
entries in the whole cache.
|
||||
If (flags == 0) remove any expired entries in the whole cache.
|
||||
|
||||
In the flags & F_FORWARD case, the return code is valid, and returns zero if the
|
||||
name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
|
||||
In the flags & F_FORWARD case, the return code is valid, and returns a non-NULL pointer
|
||||
to a cache entry if the name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
|
||||
|
||||
We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal>
|
||||
so that when we hit an entry which isn't reverse and is immortal, we're done. */
|
||||
@@ -361,7 +361,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
||||
(((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))
|
||||
{
|
||||
if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
|
||||
return 0;
|
||||
return crecp;
|
||||
*up = crecp->hash_next;
|
||||
cache_unlink(crecp);
|
||||
cache_free(crecp);
|
||||
@@ -378,7 +378,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
||||
crecp->addr.sig.type_covered == addr->addr.dnssec.type))
|
||||
{
|
||||
if (crecp->flags & F_CONFIG)
|
||||
return 0;
|
||||
return crecp;
|
||||
*up = crecp->hash_next;
|
||||
cache_unlink(crecp);
|
||||
cache_free(crecp);
|
||||
@@ -423,7 +423,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
||||
up = &crecp->hash_next;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Note: The normal calling sequence is
|
||||
@@ -471,10 +471,26 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
|
||||
return NULL;
|
||||
|
||||
/* First remove any expired entries and entries for the name/address we
|
||||
are currently inserting. Fail if we attempt to delete a name from
|
||||
/etc/hosts or DHCP. */
|
||||
if (!cache_scan_free(name, addr, now, flags))
|
||||
are currently inserting. */
|
||||
if ((new = cache_scan_free(name, addr, now, flags)))
|
||||
{
|
||||
/* We're trying to insert a record over one from
|
||||
/etc/hosts or DHCP, or other config. If the
|
||||
existing record is for an A or AAAA and
|
||||
the record we're trying to insert is the same,
|
||||
just drop the insert, but don't error the whole process. */
|
||||
if ((flags & (F_IPV4 | F_IPV6)) && (flags & F_FORWARD))
|
||||
{
|
||||
if ((flags & F_IPV4) && (new->flags & F_IPV4) &&
|
||||
new->addr.addr.addr.addr4.s_addr == addr->addr.addr4.s_addr)
|
||||
return new;
|
||||
#ifdef HAVE_IPV6
|
||||
else if ((flags & F_IPV6) && (new->flags & F_IPV6) &&
|
||||
IN6_ARE_ADDR_EQUAL(&new->addr.addr.addr.addr6, &addr->addr.addr6))
|
||||
return new;
|
||||
#endif
|
||||
}
|
||||
|
||||
insert_error = 1;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1411,7 +1427,7 @@ void dump_cache(time_t now)
|
||||
*a = 0;
|
||||
if (strlen(n) == 0 && !(cache->flags & F_REVERSE))
|
||||
n = "<Root>";
|
||||
p += sprintf(p, "%-40.40s ", n);
|
||||
p += sprintf(p, "%-30.30s ", n);
|
||||
if ((cache->flags & F_CNAME) && !is_outdated_cname_pointer(cache))
|
||||
a = cache_get_cname_target(cache);
|
||||
#ifdef HAVE_DNSSEC
|
||||
@@ -1454,7 +1470,7 @@ void dump_cache(time_t now)
|
||||
else if (cache->flags & F_DNSKEY)
|
||||
t = "K";
|
||||
#endif
|
||||
p += sprintf(p, "%-30.30s %s%s%s%s%s%s%s%s%s ", a, t,
|
||||
p += sprintf(p, "%-40.40s %s%s%s%s%s%s%s%s%s ", a, t,
|
||||
cache->flags & F_FORWARD ? "F" : " ",
|
||||
cache->flags & F_REVERSE ? "R" : " ",
|
||||
cache->flags & F_IMMORTAL ? "I" : " ",
|
||||
|
||||
+1
-1
@@ -426,7 +426,7 @@ static DBusMessage *dbus_set_bool(DBusMessage *message, int flag, char *name)
|
||||
}
|
||||
else
|
||||
{
|
||||
my_syslog(LOG_INFO, "Disabling --$s option from D-Bus", name);
|
||||
my_syslog(LOG_INFO, "Disabling --%s option from D-Bus", name);
|
||||
reset_option_bool(flag);
|
||||
}
|
||||
|
||||
|
||||
+23
-7
@@ -87,11 +87,6 @@ int main (int argc, char **argv)
|
||||
|
||||
if (daemon->edns_pktsz < PACKETSZ)
|
||||
daemon->edns_pktsz = PACKETSZ;
|
||||
#ifdef HAVE_DNSSEC
|
||||
/* Enforce min packet big enough for DNSSEC */
|
||||
if (option_bool(OPT_DNSSEC_VALID) && daemon->edns_pktsz < EDNS_PKTSZ)
|
||||
daemon->edns_pktsz = EDNS_PKTSZ;
|
||||
#endif
|
||||
|
||||
daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ?
|
||||
daemon->edns_pktsz : DNSMASQ_PACKETSZ;
|
||||
@@ -315,9 +310,15 @@ int main (int argc, char **argv)
|
||||
if (daemon->port != 0)
|
||||
{
|
||||
cache_init();
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
blockdata_init();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
if (!option_bool(OPT_NO_POLL))
|
||||
inotify_dnsmasq_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (option_bool(OPT_DBUS))
|
||||
@@ -793,6 +794,11 @@ int main (int argc, char **argv)
|
||||
|
||||
pid = getpid();
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
/* Using inotify, have to select a resolv file at startup */
|
||||
poll_resolv(1, 0, now);
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
int maxfd = -1;
|
||||
@@ -862,11 +868,16 @@ int main (int argc, char **argv)
|
||||
#if defined(HAVE_LINUX_NETWORK)
|
||||
FD_SET(daemon->netlinkfd, &rset);
|
||||
bump_maxfd(daemon->netlinkfd, &maxfd);
|
||||
if (daemon->port != 0 && !option_bool(OPT_NO_POLL))
|
||||
{
|
||||
FD_SET(daemon->inotifyfd, &rset);
|
||||
bump_maxfd(daemon->inotifyfd, &maxfd);
|
||||
}
|
||||
#elif defined(HAVE_BSD_NETWORK)
|
||||
FD_SET(daemon->routefd, &rset);
|
||||
bump_maxfd(daemon->routefd, &maxfd);
|
||||
#endif
|
||||
|
||||
|
||||
FD_SET(piperead, &rset);
|
||||
bump_maxfd(piperead, &maxfd);
|
||||
|
||||
@@ -929,6 +940,10 @@ int main (int argc, char **argv)
|
||||
route_sock();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
if (daemon->port != 0 && !option_bool(OPT_NO_POLL) && FD_ISSET(daemon->inotifyfd, &rset) && inotify_check())
|
||||
poll_resolv(1, 1, now);
|
||||
#else
|
||||
/* Check for changes to resolv files once per second max. */
|
||||
/* Don't go silent for long periods if the clock goes backwards. */
|
||||
if (daemon->last_resolv == 0 ||
|
||||
@@ -941,7 +956,8 @@ int main (int argc, char **argv)
|
||||
poll_resolv(0, daemon->last_resolv != 0, now);
|
||||
daemon->last_resolv = now;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (FD_ISSET(piperead, &rset))
|
||||
async_event(piperead, now);
|
||||
|
||||
|
||||
+11
-1
@@ -318,6 +318,7 @@ struct ds_config {
|
||||
|
||||
#define ADDRLIST_LITERAL 1
|
||||
#define ADDRLIST_IPV6 2
|
||||
#define ADDRLIST_REVONLY 4
|
||||
|
||||
struct addrlist {
|
||||
struct all_addr addr;
|
||||
@@ -541,6 +542,10 @@ struct resolvc {
|
||||
int is_default, logged;
|
||||
time_t mtime;
|
||||
char *name;
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
int wd; /* inotify watch descriptor */
|
||||
char *file; /* pointer to file part if path */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* adn-hosts parms from command-line (also dhcp-hostsfile and dhcp-optsfile */
|
||||
@@ -998,7 +1003,7 @@ extern struct daemon {
|
||||
/* DHCP state */
|
||||
int dhcpfd, helperfd, pxefd;
|
||||
#if defined(HAVE_LINUX_NETWORK)
|
||||
int netlinkfd;
|
||||
int netlinkfd, inotifyfd;
|
||||
#elif defined(HAVE_BSD_NETWORK)
|
||||
int dhcp_raw_fd, dhcp_icmp_fd, routefd;
|
||||
#endif
|
||||
@@ -1469,3 +1474,8 @@ void loop_send_probes();
|
||||
int detect_loop(char *query, int type);
|
||||
#endif
|
||||
|
||||
/* inotify.c */
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
void inotify_dnsmasq_init();
|
||||
int inotify_check(void);
|
||||
#endif
|
||||
+147
-133
@@ -456,16 +456,27 @@ static u16 *get_desc(int type)
|
||||
|
||||
/* Return bytes of canonicalised rdata, when the return value is zero, the remaining
|
||||
data, pointed to by *p, should be used raw. */
|
||||
static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff,
|
||||
static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff, int bufflen,
|
||||
unsigned char **p, u16 **desc)
|
||||
{
|
||||
int d = **desc;
|
||||
|
||||
(*desc)++;
|
||||
|
||||
/* No more data needs mangling */
|
||||
if (d == (u16)-1)
|
||||
return 0;
|
||||
{
|
||||
/* If there's more data than we have space for, just return what fits,
|
||||
we'll get called again for more chunks */
|
||||
if (end - *p > bufflen)
|
||||
{
|
||||
memcpy(buff, *p, bufflen);
|
||||
*p += bufflen;
|
||||
return bufflen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
(*desc)++;
|
||||
|
||||
if (d == 0 && extract_name(header, plen, p, buff, 1, 0))
|
||||
/* domain-name, canonicalise */
|
||||
@@ -560,7 +571,7 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
||||
if (left1 != 0)
|
||||
memmove(buff1, buff1 + len1 - left1, left1);
|
||||
|
||||
if ((len1 = get_rdata(header, plen, end1, buff1 + left1, &p1, &dp1)) == 0)
|
||||
if ((len1 = get_rdata(header, plen, end1, buff1 + left1, MAXDNAME - left1, &p1, &dp1)) == 0)
|
||||
{
|
||||
quit = 1;
|
||||
len1 = end1 - p1;
|
||||
@@ -571,7 +582,7 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
||||
if (left2 != 0)
|
||||
memmove(buff2, buff2 + len2 - left2, left2);
|
||||
|
||||
if ((len2 = get_rdata(header, plen, end2, buff2 + left2, &p2, &dp2)) == 0)
|
||||
if ((len2 = get_rdata(header, plen, end2, buff2 + left2, MAXDNAME - left2, &p2, &dp2)) == 0)
|
||||
{
|
||||
quit = 1;
|
||||
len2 = end2 - p2;
|
||||
@@ -604,6 +615,7 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
||||
Return code:
|
||||
STAT_SECURE if it validates.
|
||||
STAT_SECURE_WILDCARD if it validates and is the result of wildcard expansion.
|
||||
(In this case *wildcard_out points to the "body" of the wildcard within name.)
|
||||
STAT_NO_SIG no RRsigs found.
|
||||
STAT_INSECURE RRset empty.
|
||||
STAT_BOGUS signature is wrong, bad packet.
|
||||
@@ -614,8 +626,8 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
||||
|
||||
name is unchanged on exit. keyname is used as workspace and trashed.
|
||||
*/
|
||||
static int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class,
|
||||
int type, char *name, char *keyname, struct blockdata *key, int keylen, int algo_in, int keytag_in)
|
||||
static int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class, int type,
|
||||
char *name, char *keyname, char **wildcard_out, struct blockdata *key, int keylen, int algo_in, int keytag_in)
|
||||
{
|
||||
static unsigned char **rrset = NULL, **sigs = NULL;
|
||||
static int rrset_sz = 0, sig_sz = 0;
|
||||
@@ -787,8 +799,16 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
{
|
||||
int k;
|
||||
for (k = name_labels - labels; k != 0; k--)
|
||||
while (*name_start != '.' && *name_start != 0)
|
||||
name_start++;
|
||||
{
|
||||
while (*name_start != '.' && *name_start != 0)
|
||||
name_start++;
|
||||
if (k != 1)
|
||||
name_start++;
|
||||
}
|
||||
|
||||
if (wildcard_out)
|
||||
*wildcard_out = name_start+1;
|
||||
|
||||
name_start--;
|
||||
*name_start = '*';
|
||||
}
|
||||
@@ -808,7 +828,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
/* canonicalise rdata and calculate length of same, use name buffer as workspace */
|
||||
cp = p;
|
||||
dp = rr_desc;
|
||||
for (len = 0; (seg = get_rdata(header, plen, end, name, &cp, &dp)) != 0; len += seg);
|
||||
for (len = 0; (seg = get_rdata(header, plen, end, name, MAXDNAME, &cp, &dp)) != 0; len += seg);
|
||||
len += end - cp;
|
||||
len = htons(len);
|
||||
hash->update(ctx, 2, (unsigned char *)&len);
|
||||
@@ -816,7 +836,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
/* Now canonicalise again and digest. */
|
||||
cp = p;
|
||||
dp = rr_desc;
|
||||
while ((seg = get_rdata(header, plen, end, name, &cp, &dp)))
|
||||
while ((seg = get_rdata(header, plen, end, name, MAXDNAME, &cp, &dp)))
|
||||
hash->update(ctx, seg, (unsigned char *)name);
|
||||
if (cp != end)
|
||||
hash->update(ctx, end - cp, cp);
|
||||
@@ -963,7 +983,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
if (recp1->addr.ds.keylen == (int)hash->digest_size &&
|
||||
(ds_digest = blockdata_retrieve(recp1->addr.key.keydata, recp1->addr.ds.keylen, NULL)) &&
|
||||
memcmp(ds_digest, digest, recp1->addr.ds.keylen) == 0 &&
|
||||
validate_rrset(now, header, plen, class, T_DNSKEY, name, keyname, key, rdlen - 4, algo, keytag) == STAT_SECURE)
|
||||
validate_rrset(now, header, plen, class, T_DNSKEY, name, keyname, NULL, key, rdlen - 4, algo, keytag) == STAT_SECURE)
|
||||
{
|
||||
valid = 1;
|
||||
break;
|
||||
@@ -1432,11 +1452,88 @@ static int base32_decode(char *in, unsigned char *out)
|
||||
return p - out;
|
||||
}
|
||||
|
||||
static int check_nsec3_coverage(struct dns_header *header, size_t plen, int digest_len, unsigned char *digest, int type,
|
||||
char *workspace1, char *workspace2, unsigned char **nsecs, int nsec_count)
|
||||
{
|
||||
int i, hash_len, salt_len, base32_len, rdlen;
|
||||
unsigned char *p, *psave;
|
||||
|
||||
for (i = 0; i < nsec_count; i++)
|
||||
if ((p = nsecs[i]))
|
||||
{
|
||||
if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
|
||||
!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||
return 0;
|
||||
|
||||
p += 8; /* class, type, TTL */
|
||||
GETSHORT(rdlen, p);
|
||||
psave = p;
|
||||
p += 4; /* algo, flags, iterations */
|
||||
salt_len = *p++; /* salt_len */
|
||||
p += salt_len; /* salt */
|
||||
hash_len = *p++; /* p now points to next hashed name */
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
return 0;
|
||||
|
||||
if (digest_len == base32_len && hash_len == base32_len)
|
||||
{
|
||||
int rc = memcmp(workspace2, digest, digest_len);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
/* We found an NSEC3 whose hashed name exactly matches the query, so
|
||||
we just need to check the type map. p points to the RR data for the record. */
|
||||
|
||||
int offset = (type & 0xff) >> 3;
|
||||
int mask = 0x80 >> (type & 0x07);
|
||||
|
||||
p += hash_len; /* skip next-domain hash */
|
||||
rdlen -= p - psave;
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
return 0;
|
||||
|
||||
while (rdlen >= 2)
|
||||
{
|
||||
if (p[0] == type >> 8)
|
||||
{
|
||||
/* Does the NSEC3 say our type exists? */
|
||||
if (offset < p[1] && (p[offset+2] & mask) != 0)
|
||||
return STAT_BOGUS;
|
||||
|
||||
break; /* finshed checking */
|
||||
}
|
||||
|
||||
rdlen -= p[1];
|
||||
p += p[1];
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if (rc <= 0)
|
||||
{
|
||||
/* Normal case, hash falls between NSEC3 name-hash and next domain name-hash,
|
||||
wrap around case, name-hash falls between NSEC3 name-hash and end */
|
||||
if (memcmp(p, digest, digest_len) > 0 || memcmp(workspace2, p, digest_len) > 0)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wrap around case, name falls between start and next domain name */
|
||||
if (memcmp(workspace2, p, digest_len) > 0 && memcmp(p, digest, digest_len) > 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, unsigned char **nsecs, int nsec_count,
|
||||
char *workspace1, char *workspace2, char *name, int type)
|
||||
char *workspace1, char *workspace2, char *name, int type, char *wildname)
|
||||
{
|
||||
unsigned char *salt, *p, *digest;
|
||||
int digest_len, i, iterations, salt_len, hash_len, base32_len, algo = 0;
|
||||
int digest_len, i, iterations, salt_len, base32_len, algo = 0;
|
||||
struct nettle_hash const *hash;
|
||||
char *closest_encloser, *next_closest, *wildcard;
|
||||
|
||||
@@ -1509,7 +1606,14 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
if (!(hash = hash_find("sha1")))
|
||||
return STAT_BOGUS;
|
||||
|
||||
/* Now, we need the "closest encloser NSEC3" */
|
||||
if ((digest_len = hash_name(name, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count))
|
||||
return STAT_SECURE;
|
||||
|
||||
/* Can't find an NSEC3 which covers the name directly, we need the "closest encloser NSEC3"
|
||||
or an answer inferred from a wildcard record. */
|
||||
closest_encloser = name;
|
||||
next_closest = NULL;
|
||||
|
||||
@@ -1518,6 +1622,9 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
if (*closest_encloser == '.')
|
||||
closest_encloser++;
|
||||
|
||||
if (wildname && hostname_isequal(closest_encloser, wildname))
|
||||
break;
|
||||
|
||||
if ((digest_len = hash_name(closest_encloser, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
return STAT_BOGUS;
|
||||
|
||||
@@ -1540,127 +1647,33 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
}
|
||||
while ((closest_encloser = strchr(closest_encloser, '.')));
|
||||
|
||||
/* No usable NSEC3s */
|
||||
if (i == nsec_count)
|
||||
if (!closest_encloser)
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (!next_closest)
|
||||
{
|
||||
/* We found an NSEC3 whose hashed name exactly matches the query, so
|
||||
Now we just need to check the type map. p points to the RR data for the record. */
|
||||
int rdlen;
|
||||
unsigned char *psave;
|
||||
int offset = (type & 0xff) >> 3;
|
||||
int mask = 0x80 >> (type & 0x07);
|
||||
|
||||
p += 8; /* class, type, TTL */
|
||||
GETSHORT(rdlen, p);
|
||||
psave = p;
|
||||
p += 5 + salt_len; /* algo, flags, iterations, salt_len, salt */
|
||||
hash_len = *p++;
|
||||
if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
p += hash_len;
|
||||
rdlen -= p - psave;
|
||||
|
||||
while (rdlen >= 2)
|
||||
{
|
||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (p[0] == type >> 8)
|
||||
{
|
||||
/* Does the NSEC3 say our type exists? */
|
||||
if (offset < p[1] && (p[offset+2] & mask) != 0)
|
||||
return STAT_BOGUS;
|
||||
|
||||
break; /* finshed checking */
|
||||
}
|
||||
|
||||
rdlen -= p[1];
|
||||
p += p[1];
|
||||
}
|
||||
|
||||
return STAT_SECURE;
|
||||
}
|
||||
|
||||
/* Look for NSEC3 that proves the non-existence of the next-closest encloser */
|
||||
if ((digest_len = hash_name(next_closest, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
return STAT_BOGUS;
|
||||
|
||||
for (i = 0; i < nsec_count; i++)
|
||||
if ((p = nsecs[i]))
|
||||
{
|
||||
if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
|
||||
!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||
return STAT_BOGUS;
|
||||
|
||||
p += 15 + salt_len; /* class, type, TTL, rdlen, algo, flags, iterations, salt_len, salt */
|
||||
hash_len = *p++; /* p now points to next hashed name */
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (digest_len == base32_len && hash_len == base32_len)
|
||||
{
|
||||
if (memcmp(workspace2, digest, digest_len) <= 0)
|
||||
{
|
||||
/* Normal case, hash falls between NSEC3 name-hash and next domain name-hash,
|
||||
wrap around case, name-hash falls between NSEC3 name-hash and end */
|
||||
if (memcmp(p, digest, digest_len) > 0 || memcmp(workspace2, p, digest_len) > 0)
|
||||
return STAT_SECURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wrap around case, name falls between start and next domain name */
|
||||
if (memcmp(workspace2, p, digest_len) > 0 && memcmp(p, digest, digest_len) > 0)
|
||||
return STAT_SECURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count))
|
||||
return STAT_BOGUS;
|
||||
|
||||
/* Finally, check that there's no seat of wildcard synthesis */
|
||||
if (!(wildcard = strchr(next_closest, '.')) || wildcard == next_closest)
|
||||
return STAT_BOGUS;
|
||||
if (!wildname)
|
||||
{
|
||||
if (!(wildcard = strchr(next_closest, '.')) || wildcard == next_closest)
|
||||
return STAT_BOGUS;
|
||||
|
||||
wildcard--;
|
||||
*wildcard = '*';
|
||||
|
||||
if ((digest_len = hash_name(wildcard, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count))
|
||||
return STAT_BOGUS;
|
||||
}
|
||||
|
||||
wildcard--;
|
||||
*wildcard = '*';
|
||||
|
||||
if ((digest_len = hash_name(wildcard, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
return STAT_BOGUS;
|
||||
|
||||
for (i = 0; i < nsec_count; i++)
|
||||
if ((p = nsecs[i]))
|
||||
{
|
||||
if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
|
||||
!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||
return STAT_BOGUS;
|
||||
|
||||
p += 15 + salt_len; /* class, type, TTL, rdlen, algo, flags, iterations, salt_len, salt */
|
||||
hash_len = *p++; /* p now points to next hashed name */
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (digest_len == base32_len && hash_len == base32_len)
|
||||
{
|
||||
if (memcmp(workspace2, digest, digest_len) <= 0)
|
||||
{
|
||||
/* Normal case, hash falls between NSEC3 name-hash and next domain name-hash,
|
||||
wrap around case, name-hash falls between NSEC3 name-hash and end */
|
||||
if (memcmp(p, digest, digest_len) > 0 || memcmp(workspace2, p, digest_len) > 0)
|
||||
return STAT_SECURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wrap around case, name falls between start and next domain name */
|
||||
if (memcmp(workspace2, p, digest_len) > 0 && memcmp(p, digest, digest_len) > 0)
|
||||
return STAT_SECURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STAT_BOGUS;
|
||||
return STAT_SECURE;
|
||||
}
|
||||
|
||||
/* Validate all the RRsets in the answer and authority sections of the reply (4035:3.2.3) */
|
||||
@@ -1781,8 +1794,9 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
struct all_addr a;
|
||||
struct blockdata *key;
|
||||
struct crec *crecp;
|
||||
|
||||
rc = validate_rrset(now, header, plen, class1, type1, name, keyname, NULL, 0, 0, 0);
|
||||
char *wildname;
|
||||
|
||||
rc = validate_rrset(now, header, plen, class1, type1, name, keyname, &wildname, NULL, 0, 0, 0);
|
||||
|
||||
if (rc == STAT_SECURE_WILDCARD)
|
||||
{
|
||||
@@ -1796,7 +1810,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
if (nsec_type == T_NSEC)
|
||||
rc = prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1);
|
||||
else
|
||||
rc = prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1);
|
||||
rc = prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1, wildname);
|
||||
|
||||
if (rc != STAT_SECURE)
|
||||
return rc;
|
||||
@@ -1922,7 +1936,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
if (nsec_type == T_NSEC)
|
||||
return prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype);
|
||||
else
|
||||
return prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype);
|
||||
return prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype, NULL);
|
||||
}
|
||||
|
||||
/* Chase the CNAME chain in the packet until the first record which _doesn't validate.
|
||||
@@ -1969,7 +1983,7 @@ int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char
|
||||
return STAT_INSECURE;
|
||||
|
||||
/* validate CNAME chain, return if insecure or need more data */
|
||||
rc = validate_rrset(now, header, plen, class, type, name, keyname, NULL, 0, 0, 0);
|
||||
rc = validate_rrset(now, header, plen, class, type, name, keyname, NULL, NULL, 0, 0, 0);
|
||||
if (rc != STAT_SECURE)
|
||||
{
|
||||
if (rc == STAT_NO_SIG)
|
||||
|
||||
+20
-20
@@ -1048,7 +1048,7 @@ void receive_query(struct listener *listen, time_t now)
|
||||
/* packet buffer overwritten */
|
||||
daemon->srv_save = NULL;
|
||||
|
||||
dst_addr_4.s_addr = 0;
|
||||
dst_addr_4.s_addr = dst_addr.addr.addr4.s_addr = 0;
|
||||
netmask.s_addr = 0;
|
||||
|
||||
if (option_bool(OPT_NOWILD) && listen->iface)
|
||||
@@ -1057,7 +1057,7 @@ void receive_query(struct listener *listen, time_t now)
|
||||
|
||||
if (listen->family == AF_INET)
|
||||
{
|
||||
dst_addr_4 = listen->iface->addr.in.sin_addr;
|
||||
dst_addr_4 = dst_addr.addr.addr4 = listen->iface->addr.in.sin_addr;
|
||||
netmask = listen->iface->netmask;
|
||||
}
|
||||
}
|
||||
@@ -1796,6 +1796,24 @@ unsigned char *tcp_request(int confd, time_t now,
|
||||
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 (option_bool(OPT_CONNTRACK))
|
||||
{
|
||||
unsigned int mark;
|
||||
struct all_addr local;
|
||||
#ifdef HAVE_IPV6
|
||||
if (local_addr->sa.sa_family == AF_INET6)
|
||||
local.addr.addr6 = local_addr->in6.sin6_addr;
|
||||
else
|
||||
#endif
|
||||
local.addr.addr4 = local_addr->in.sin_addr;
|
||||
|
||||
if (get_incoming_mark(&peer_addr, &local, 1, &mark))
|
||||
setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((!local_bind(last_server->tcpfd, &last_server->source_addr, last_server->interface, 1) ||
|
||||
connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
|
||||
{
|
||||
@@ -1820,24 +1838,6 @@ unsigned char *tcp_request(int confd, time_t now,
|
||||
size = new_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONNTRACK
|
||||
/* Copy connection mark of incoming query to outgoing connection. */
|
||||
if (option_bool(OPT_CONNTRACK))
|
||||
{
|
||||
unsigned int mark;
|
||||
struct all_addr local;
|
||||
#ifdef HAVE_IPV6
|
||||
if (local_addr->sa.sa_family == AF_INET6)
|
||||
local.addr.addr6 = local_addr->in6.sin6_addr;
|
||||
else
|
||||
#endif
|
||||
local.addr.addr4 = local_addr->in.sin_addr;
|
||||
|
||||
if (get_incoming_mark(&peer_addr, &local, 1, &mark))
|
||||
setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
*length = htons(size);
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 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"
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
|
||||
/* the strategy is to set a inotify on the directories containing
|
||||
resolv files, for any files in the directory which are close-write
|
||||
or moved into the directory.
|
||||
|
||||
When either of those happen, we look to see if the file involved
|
||||
is actually a resolv-file, and if so, call poll-resolv with
|
||||
the "force" argument, to ensure it's read.
|
||||
|
||||
This adds one new error condition: the directories containing
|
||||
all specified resolv-files must exist at start-up, even if the actual
|
||||
files don't.
|
||||
*/
|
||||
|
||||
static char *inotify_buffer;
|
||||
#define INOTIFY_SZ (sizeof(struct inotify_event) + NAME_MAX + 1)
|
||||
|
||||
void inotify_dnsmasq_init()
|
||||
{
|
||||
struct resolvc *res;
|
||||
|
||||
inotify_buffer = safe_malloc(INOTIFY_SZ);
|
||||
|
||||
|
||||
daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||
|
||||
if (daemon->inotifyfd == -1)
|
||||
die(_("failed to create inotify: %s"), NULL, EC_MISC);
|
||||
|
||||
for (res = daemon->resolv_files; res; res = res->next)
|
||||
{
|
||||
char *d = NULL, *path;
|
||||
|
||||
if (!(path = realpath(res->name, NULL)))
|
||||
{
|
||||
/* realpath will fail if the file doesn't exist, but
|
||||
dnsmasq copes with missing files, so fall back
|
||||
and assume that symlinks are not in use in that case. */
|
||||
if (errno == ENOENT)
|
||||
path = res->name;
|
||||
else
|
||||
die(_("cannot cannonicalise resolv-file %s: %s"), res->name, EC_MISC);
|
||||
}
|
||||
|
||||
if ((d = strrchr(path, '/')))
|
||||
{
|
||||
*d = 0; /* make path just directory */
|
||||
res->wd = inotify_add_watch(daemon->inotifyfd, path, IN_CLOSE_WRITE | IN_MOVED_TO);
|
||||
res->file = d+1; /* pointer to filename */
|
||||
*d = '/';
|
||||
|
||||
if (res->wd == -1 && errno == ENOENT)
|
||||
die(_("directory %s for resolv-file is missing, cannot poll"), res->name, EC_MISC);
|
||||
|
||||
if (res->wd == -1)
|
||||
die(_("failed to create inotify for %s: %s"), res->name, EC_MISC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int inotify_check(void)
|
||||
{
|
||||
int hit = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int rc;
|
||||
char *p;
|
||||
struct resolvc *res;
|
||||
struct inotify_event *in;
|
||||
|
||||
while ((rc = read(daemon->inotifyfd, inotify_buffer, INOTIFY_SZ)) == -1 && errno == EINTR);
|
||||
|
||||
if (rc <= 0)
|
||||
break;
|
||||
|
||||
for (p = inotify_buffer; rc - (p - inotify_buffer) >= (int)sizeof(struct inotify_event); p += sizeof(struct inotify_event) + in->len)
|
||||
{
|
||||
in = (struct inotify_event*)p;
|
||||
|
||||
for (res = daemon->resolv_files; res; res = res->next)
|
||||
if (res->wd == in->wd && in->len != 0 && strcmp(res->file, in->name) == 0)
|
||||
hit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+8
-8
@@ -16,10 +16,6 @@
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
#ifndef IN6_IS_ADDR_ULA
|
||||
#define IN6_IS_ADDR_ULA(a) ((((__const uint32_t *) (a))[0] & htonl (0xfe00000)) == htonl (0xfc000000))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
|
||||
int indextoname(int fd, int index, char *name)
|
||||
@@ -240,7 +236,7 @@ struct iface_param {
|
||||
};
|
||||
|
||||
static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
union mysockaddr *addr, struct in_addr netmask, int prefixlen, int dad)
|
||||
union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags)
|
||||
{
|
||||
struct irec *iface;
|
||||
int mtu = 0, loopback;
|
||||
@@ -392,6 +388,10 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
{
|
||||
al->addr.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;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -403,7 +403,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
for (iface = daemon->interfaces; iface; iface = iface->next)
|
||||
if (sockaddr_isequal(&iface->addr, addr))
|
||||
{
|
||||
iface->dad = dad;
|
||||
iface->dad = !!(iface_flags & IFACE_TENTATIVE);
|
||||
iface->found = 1; /* for garbage collection */
|
||||
return 1;
|
||||
}
|
||||
@@ -478,7 +478,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
iface->dhcp_ok = dhcp_ok;
|
||||
iface->dns_auth = auth_dns;
|
||||
iface->mtu = mtu;
|
||||
iface->dad = dad;
|
||||
iface->dad = !!(iface_flags & IFACE_TENTATIVE);
|
||||
iface->found = 1;
|
||||
iface->done = iface->multicast_done = iface->warned = 0;
|
||||
iface->index = if_index;
|
||||
@@ -523,7 +523,7 @@ static int iface_allowed_v6(struct in6_addr *local, int prefix,
|
||||
else
|
||||
addr.in6.sin6_scope_id = 0;
|
||||
|
||||
return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, !!(flags & IFACE_TENTATIVE));
|
||||
return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+39
-17
@@ -1474,22 +1474,25 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
for (arg = comma; arg; arg = comma)
|
||||
{
|
||||
comma = split(arg);
|
||||
li = opt_malloc(sizeof(struct list));
|
||||
if (*arg == '*')
|
||||
if (strlen(arg) != 0)
|
||||
{
|
||||
li->next = match_suffix;
|
||||
match_suffix = li;
|
||||
/* Have to copy: buffer is overwritten */
|
||||
li->suffix = opt_string_alloc(arg+1);
|
||||
li = opt_malloc(sizeof(struct list));
|
||||
if (*arg == '*')
|
||||
{
|
||||
li->next = match_suffix;
|
||||
match_suffix = li;
|
||||
/* Have to copy: buffer is overwritten */
|
||||
li->suffix = opt_string_alloc(arg+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
li->next = ignore_suffix;
|
||||
ignore_suffix = li;
|
||||
/* Have to copy: buffer is overwritten */
|
||||
li->suffix = opt_string_alloc(arg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
li->next = ignore_suffix;
|
||||
ignore_suffix = li;
|
||||
/* Have to copy: buffer is overwritten */
|
||||
li->suffix = opt_string_alloc(arg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!(dir_stream = opendir(directory)))
|
||||
die(_("cannot access directory %s: %s"), directory, EC_FILE);
|
||||
@@ -1555,7 +1558,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
free(ignore_suffix->suffix);
|
||||
free(ignore_suffix);
|
||||
}
|
||||
|
||||
for(; match_suffix; match_suffix = li)
|
||||
{
|
||||
li = match_suffix->next;
|
||||
free(match_suffix->suffix);
|
||||
free(match_suffix);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1933,10 +1941,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
else
|
||||
{
|
||||
/* generate the equivalent of
|
||||
local=/<domain>/
|
||||
local=/xxx.yyy.zzz.in-addr.arpa/ */
|
||||
struct server *serv = add_rev4(new->start, msize);
|
||||
serv->flags |= SERV_NO_ADDR;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1970,10 +1985,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
else
|
||||
{
|
||||
/* generate the equivalent of
|
||||
local=/<domain>/
|
||||
local=/xxx.yyy.zzz.ip6.arpa/ */
|
||||
struct server *serv = add_rev6(&new->start6, msize);
|
||||
serv->flags |= SERV_NO_ADDR;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-7
@@ -1923,14 +1923,17 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||
if (hostname_isequal(name, intr->name))
|
||||
{
|
||||
ans = 1;
|
||||
if (!dryrun)
|
||||
{
|
||||
|
||||
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||
#ifdef HAVE_IPV6
|
||||
if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
|
||||
if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
if (addrlist->flags & ADDRLIST_REVONLY)
|
||||
continue;
|
||||
#endif
|
||||
ans = 1;
|
||||
if (!dryrun)
|
||||
{
|
||||
gotit = 1;
|
||||
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
|
||||
@@ -1939,7 +1942,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
type == T_A ? "4" : "6", &addrlist->addr))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dryrun && !gotit)
|
||||
|
||||
+25
-2
@@ -691,6 +691,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||
#endif
|
||||
|
||||
o = build_ia(state, &t1cntr);
|
||||
if (address_assigned)
|
||||
address_assigned = 2;
|
||||
|
||||
for (ia_counter = 0; ia_option; ia_counter++, ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
|
||||
{
|
||||
@@ -781,6 +783,27 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||
address_assigned = 1;
|
||||
}
|
||||
|
||||
if (address_assigned != 1)
|
||||
{
|
||||
/* If the server will not assign any addresses to any IAs in a
|
||||
subsequent Request from the client, the server MUST send an Advertise
|
||||
message to the client that doesn't include any IA options. */
|
||||
if (!state->lease_allocate)
|
||||
{
|
||||
save_counter(o);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the server cannot assign any addresses to an IA in the message
|
||||
from the client, the server MUST include the IA in the Reply message
|
||||
with no addresses in the IA and a Status Code option in the IA
|
||||
containing status code NoAddrsAvail. */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6NOADDRS);
|
||||
put_opt6_string(_("address unavailable"));
|
||||
end_opt6(o1);
|
||||
}
|
||||
|
||||
end_ia(t1cntr, min_time, 0);
|
||||
end_opt6(o);
|
||||
}
|
||||
@@ -806,7 +829,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||
put_opt6_short(DHCP6NOADDRS);
|
||||
put_opt6_string(_("no addresses available"));
|
||||
end_opt6(o1);
|
||||
log6_packet(state, "DHCPADVERTISE", NULL, _("no addresses available"));
|
||||
log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, _("no addresses available"));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -862,7 +885,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||
{
|
||||
/* Static range, not configured. */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6UNSPEC);
|
||||
put_opt6_short(DHCP6NOADDRS);
|
||||
put_opt6_string(_("address unavailable"));
|
||||
end_opt6(o1);
|
||||
}
|
||||
|
||||
+5
-1
@@ -20,6 +20,10 @@
|
||||
|
||||
#if defined(HAVE_IPSET) && defined(HAVE_BSD_NETWORK)
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#include <bsd/string.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
@@ -136,7 +140,7 @@ int add_to_ipset(const char *setname, const struct all_addr *ipaddr,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc = pfr_add_tables(&table, 1, &n, 0))
|
||||
if ((rc = pfr_add_tables(&table, 1, &n, 0)))
|
||||
{
|
||||
my_syslog(LOG_WARNING, _("warning: pfr_add_tables: %s(%d)"),
|
||||
pfr_strerror(errno),rc);
|
||||
|
||||
Reference in new issue
Block a user