From c3e195433152f91a3f14d59d6ea10e8963e6308d Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Fri, 12 Jun 2015 17:15:51 +0200 Subject: [PATCH 1/7] strongswan: Update to 5.3.2 This release fixes a security issue filed under CVE-2015-4171. https://www.strongswan.org/blog/2015/06/08/strongswan-vulnerability-(cve-2015-4171).html Signed-off-by: Michael Tremer --- lfs/strongswan | 6 ++---- src/patches/strongswan-5.3.1-build-timeattack.patch | 11 ----------- 2 files changed, 2 insertions(+), 15 deletions(-) delete mode 100644 src/patches/strongswan-5.3.1-build-timeattack.patch diff --git a/lfs/strongswan b/lfs/strongswan index d1a5b8c15..b4438dda5 100644 --- a/lfs/strongswan +++ b/lfs/strongswan @@ -24,7 +24,7 @@ include Config -VER = 5.3.1 +VER = 5.3.2 THISAPP = strongswan-$(VER) DL_FILE = $(THISAPP).tar.bz2 @@ -48,7 +48,7 @@ objects = $(DL_FILE) $(DL_FILE) = $(DL_FROM)/$(DL_FILE) -$(DL_FILE)_MD5 = 66f258901a3d6c271da1a0c7fb3e5013 +$(DL_FILE)_MD5 = fab014be1477ef4ebf9a765e10f8802c install : $(TARGET) @@ -78,10 +78,8 @@ $(subst %,%_MD5,$(objects)) : $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/strongswan-5.3.1-build-timeattack.patch cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/strongswan-ipfire.patch - cd $(DIR_APP) && autoreconf -vfi cd $(DIR_APP) && ./configure \ --prefix="/usr" \ --sysconfdir="/etc" \ diff --git a/src/patches/strongswan-5.3.1-build-timeattack.patch b/src/patches/strongswan-5.3.1-build-timeattack.patch deleted file mode 100644 index 948c4fc73..000000000 --- a/src/patches/strongswan-5.3.1-build-timeattack.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- strongswan-5.3.1/scripts/Makefile.am.old 2015-06-04 17:20:43.539244145 +0000 -+++ strongswan-5.3.1/scripts/Makefile.am 2015-06-04 17:20:51.760510631 +0000 -@@ -42,7 +42,7 @@ - dnssec_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la - aes_test_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la - settings_test_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la --timeattack_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -+timeattack_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la $(RTLIB) - - key2keyid.o : $(top_builddir)/config.status - From 5cba4356690f1282b506844505d81bc8b050d32e Mon Sep 17 00:00:00 2001 From: Arne Fitzenreiter Date: Fri, 12 Jun 2015 17:54:03 +0200 Subject: [PATCH 2/7] core91: rebuild grub.cfg to display new core version. --- config/rootfiles/core/91/update.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/rootfiles/core/91/update.sh b/config/rootfiles/core/91/update.sh index 1e55e8bd5..1104c9fa4 100644 --- a/config/rootfiles/core/91/update.sh +++ b/config/rootfiles/core/91/update.sh @@ -54,6 +54,11 @@ if [ `grep "ENABLED=on" /var/ipfire/vpn/settings` ]; then /etc/init.d/ipsec start fi +# Update grub config to display new core version +if [ -e /boot/grub/grub.cfg ]; then + grub-mkconfig > /boot/grub/grub.cfg +fi + # This update need a reboot... touch /var/run/need_reboot From 1f99566dd268515c18a8d8ae2e8ab526c490b99b Mon Sep 17 00:00:00 2001 From: Arne Fitzenreiter Date: Fri, 12 Jun 2015 17:54:38 +0200 Subject: [PATCH 3/7] openssl: update to 1.0.2c fix ABI problems. --- lfs/openssl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lfs/openssl b/lfs/openssl index 3b9f3e121..1abc92cdf 100644 --- a/lfs/openssl +++ b/lfs/openssl @@ -24,7 +24,7 @@ include Config -VER = 1.0.2b +VER = 1.0.2c THISAPP = openssl-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -82,7 +82,7 @@ objects = $(DL_FILE) $(DL_FILE) = $(DL_FROM)/$(DL_FILE) -$(DL_FILE)_MD5 = 7729b259e2dea7d60b32fc3934d6984b +$(DL_FILE)_MD5 = 8c8d81a9ae7005276e486702edbcd4b6 install : $(TARGET) From 52109114334696b87bd158b40a5ab88d9360e7b9 Mon Sep 17 00:00:00 2001 From: Arne Fitzenreiter Date: Wed, 8 Jul 2015 19:41:09 +0200 Subject: [PATCH 4/7] asterisk: update rootfile. --- config/rootfiles/packages/asterisk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) mode change 100755 => 100644 config/rootfiles/packages/asterisk diff --git a/config/rootfiles/packages/asterisk b/config/rootfiles/packages/asterisk old mode 100755 new mode 100644 index de75232c1..1d5c2a0ad --- a/config/rootfiles/packages/asterisk +++ b/config/rootfiles/packages/asterisk @@ -1,6 +1,5 @@ etc/asterisk etc/logrotate.d/asterisk -etc/rc.d/init.d/asterisk etc/rc.d/rc0.d/K30asterisk etc/rc.d/rc3.d/S30asterisk etc/rc.d/rc6.d/K30asterisk @@ -152,6 +151,7 @@ etc/rc.d/rc6.d/K30asterisk #usr/include/asterisk/ulaw.h #usr/include/asterisk/unaligned.h #usr/include/asterisk/utils.h +#usr/include/asterisk/vector.h #usr/include/asterisk/version.h #usr/include/asterisk/xml.h #usr/include/asterisk/xmldoc.h @@ -956,6 +956,7 @@ var/lib/asterisk/sounds/en/bar.gsm var/lib/asterisk/sounds/en/barn.gsm var/lib/asterisk/sounds/en/barns.gsm var/lib/asterisk/sounds/en/barometric.gsm +var/lib/asterisk/sounds/en/basic-pbx-ivr-main.gsm var/lib/asterisk/sounds/en/bearing.gsm var/lib/asterisk/sounds/en/beaufort.gsm var/lib/asterisk/sounds/en/because-paranoid.gsm @@ -2855,3 +2856,4 @@ var/spool/asterisk/voicemail/default/1234/INBOX var/spool/asterisk/voicemail/default/1234/en var/spool/asterisk/voicemail/default/1234/en/busy.gsm var/spool/asterisk/voicemail/default/1234/en/unavail.gsm +etc/rc.d/init.d/asterisk From c50d4f54b6090962f0b7f1081711a0f8185cf268 Mon Sep 17 00:00:00 2001 From: Arne Fitzenreiter Date: Thu, 9 Jul 2015 12:41:11 +0200 Subject: [PATCH 5/7] kernel: fix missing rootdev on xen installation. --- src/paks/linux-pae/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/paks/linux-pae/install.sh b/src/paks/linux-pae/install.sh index 27e665f92..4ebb38bf2 100644 --- a/src/paks/linux-pae/install.sh +++ b/src/paks/linux-pae/install.sh @@ -45,7 +45,7 @@ function find_partition() { extract_files # KVER=xxxKVERxxx - +ROOT=`find_partition /` # # Create new module depency # From d6c40f585dfe3f346651d53fb1bebaf0dae51a4f Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 9 Jul 2015 12:29:37 +0200 Subject: [PATCH 6/7] squid: Apply fix for Squid Advisory SQUID-2015:2 Squid configured with cache_peer and operating on explicit proxy traffic does not correctly handle CONNECT method peer responses. The bug is important because it allows remote clients to bypass security in an explicit gateway proxy. However, the bug is exploitable only if you have configured cache_peer to receive CONNECT requests. http://www.squid-cache.org/Advisories/SQUID-2015_2.txt Signed-off-by: Michael Tremer --- config/rootfiles/core/92/filelists/squid | 1 + lfs/squid | 1 + src/patches/squid-3.4-13225.patch | 284 +++++++++++++++++++++++ 3 files changed, 286 insertions(+) create mode 120000 config/rootfiles/core/92/filelists/squid create mode 100644 src/patches/squid-3.4-13225.patch diff --git a/config/rootfiles/core/92/filelists/squid b/config/rootfiles/core/92/filelists/squid new file mode 120000 index 000000000..2dc8372a0 --- /dev/null +++ b/config/rootfiles/core/92/filelists/squid @@ -0,0 +1 @@ +../../../common/squid \ No newline at end of file diff --git a/lfs/squid b/lfs/squid index d4fc4c5a1..a338660bb 100644 --- a/lfs/squid +++ b/lfs/squid @@ -70,6 +70,7 @@ $(subst %,%_MD5,$(objects)) : $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar xaf $(DIR_DL)/$(DL_FILE) + cd $(DIR_APP) && patch -Np0 < $(DIR_SRC)/src/patches/squid-3.4-13225.patch cd $(DIR_APP) && ./configure \ --prefix=/usr \ --sysconfdir=/etc/squid \ diff --git a/src/patches/squid-3.4-13225.patch b/src/patches/squid-3.4-13225.patch new file mode 100644 index 000000000..9ccec5ead --- /dev/null +++ b/src/patches/squid-3.4-13225.patch @@ -0,0 +1,284 @@ +------------------------------------------------------------ +revno: 13225 +revision-id: squid3@treenet.co.nz-20150709032133-qg1patn5zngt4o4h +parent: squid3@treenet.co.nz-20150501100500-3utkhrao1yrd8ig6 +author: Alex Rousskov +committer: Amos Jeffries +branch nick: 3.4 +timestamp: Wed 2015-07-08 20:21:33 -0700 +message: + Do not blindly forward cache peer CONNECT responses. + + Squid blindly forwards cache peer CONNECT responses to clients. This + may break things if the peer responds with something like HTTP 403 + (Forbidden) and keeps the connection with Squid open: + - The client application issues a CONNECT request. + - Squid forwards this request to a cache peer. + - Cache peer correctly responds back with a "403 Forbidden". + - Squid does not parse cache peer response and + just forwards it as if it was a Squid response to the client. + - The TCP connections are not closed. + + At this stage, Squid is unaware that the CONNECT request has failed. All + subsequent requests on the user agent TCP connection are treated as + tunnelled traffic. Squid is forwarding these requests to the peer on the + TCP connection previously used for the 403-ed CONNECT request, without + proper processing. The additional headers which should have been applied + by Squid to these requests are not applied, and the requests are being + forwarded to the cache peer even though the Squid configuration may + state that these requests must go directly to the origin server. + + This fixes Squid to parse cache peer responses, and if an error response + found, respond with "502 Bad Gateway" to the client and close the + connections. +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20150709032133-qg1patn5zngt4o4h +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.4 +# testament_sha1: 6cbce093f30c8a09173eb610eaa423c7c305ff23 +# timestamp: 2015-07-09 03:40:35 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.4 +# base_revision_id: squid3@treenet.co.nz-20150501100500-\ +# 3utkhrao1yrd8ig6 +# +# Begin patch +=== modified file 'src/tunnel.cc' +--- src/tunnel.cc 2014-04-26 10:58:22 +0000 ++++ src/tunnel.cc 2015-07-09 03:21:33 +0000 +@@ -122,6 +122,10 @@ + (request->flags.interceptTproxy || request->flags.intercepted)); + } + ++ /// Sends "502 Bad Gateway" error response to the client, ++ /// if it is waiting for Squid CONNECT response, closing connections. ++ void informUserOfPeerError(const char *errMsg); ++ + class Connection + { + +@@ -139,13 +143,14 @@ + + void error(int const xerrno); + int debugLevelForError(int const xerrno) const; +- /// handles a non-I/O error associated with this Connection +- void logicError(const char *errMsg); + void closeIfOpen(); + void dataSent (size_t amount); ++ /// writes 'b' buffer, setting the 'writer' member to 'callback'. ++ void write(const char *b, int size, AsyncCall::Pointer &callback, FREE * free_func); + int len; + char *buf; + int64_t *size_ptr; /* pointer to size in an ConnStateData for logging */ ++ AsyncCall::Pointer writer; ///< pending Comm::Write callback + + Comm::ConnectionPointer conn; ///< The currently connected connection. + +@@ -195,13 +200,14 @@ + TunnelStateData *tunnelState = (TunnelStateData *)params.data; + debugs(26, 3, HERE << tunnelState->server.conn); + tunnelState->server.conn = NULL; ++ tunnelState->server.writer = NULL; + + if (tunnelState->noConnections()) { + delete tunnelState; + return; + } + +- if (!tunnelState->server.len) { ++ if (!tunnelState->client.writer) { + tunnelState->client.conn->close(); + return; + } +@@ -213,13 +219,14 @@ + TunnelStateData *tunnelState = (TunnelStateData *)params.data; + debugs(26, 3, HERE << tunnelState->client.conn); + tunnelState->client.conn = NULL; ++ tunnelState->client.writer = NULL; + + if (tunnelState->noConnections()) { + delete tunnelState; + return; + } + +- if (!tunnelState->client.len) { ++ if (!tunnelState->server.writer) { + tunnelState->server.conn->close(); + return; + } +@@ -343,6 +350,23 @@ + handleConnectResponse(len); + } + ++void ++TunnelStateData::informUserOfPeerError(const char *errMsg) ++{ ++ server.len = 0; ++ if (!clientExpectsConnectResponse()) { ++ // closing the connection is the best we can do here ++ debugs(50, 3, server.conn << " closing on error: " << errMsg); ++ server.conn->close(); ++ return; ++ } ++ ErrorState *err = new ErrorState(ERR_CONNECT_FAIL, Http::scBadGateway, request.getRaw()); ++ err->callback = tunnelErrorComplete; ++ err->callback_data = this; ++ *status_ptr = Http::scBadGateway; ++ errorSend(http->getConn()->clientConnection, err); ++} ++ + /* Read from client side and queue it for writing to the server */ + void + TunnelStateData::ReadConnectResponseDone(const Comm::ConnectionPointer &, char *buf, size_t len, comm_err_t errcode, int xerrno, void *data) +@@ -374,7 +398,7 @@ + const bool parsed = rep.parse(connectRespBuf, eof, &parseErr); + if (!parsed) { + if (parseErr > 0) { // unrecoverable parsing error +- server.logicError("malformed CONNECT response from peer"); ++ informUserOfPeerError("malformed CONNECT response from peer"); + return; + } + +@@ -383,7 +407,7 @@ + assert(!parseErr); + + if (!connectRespBuf->hasSpace()) { +- server.logicError("huge CONNECT response from peer"); ++ informUserOfPeerError("huge CONNECT response from peer"); + return; + } + +@@ -397,7 +421,8 @@ + + // bail if we did not get an HTTP 200 (Connection Established) response + if (rep.sline.status() != Http::scOkay) { +- server.logicError("unsupported CONNECT response status code"); ++ // if we ever decide to reuse the peer connection, we must extract the error response first ++ informUserOfPeerError("unsupported CONNECT response status code"); + return; + } + +@@ -416,13 +441,6 @@ + } + + void +-TunnelStateData::Connection::logicError(const char *errMsg) +-{ +- debugs(50, 3, conn << " closing on error: " << errMsg); +- conn->close(); +-} +- +-void + TunnelStateData::Connection::error(int const xerrno) + { + /* XXX fixme xstrerror and xerrno... */ +@@ -517,7 +535,7 @@ + debugs(26, 3, HERE << "Schedule Write"); + AsyncCall::Pointer call = commCbCall(5,5, "TunnelBlindCopyWriteHandler", + CommIoCbPtrFun(completion, this)); +- Comm::Write(to.conn, from.buf, len, call, NULL); ++ to.write(from.buf, len, call, NULL); + } + + /* Writes data from the client buffer to the server side */ +@@ -526,6 +544,7 @@ + { + TunnelStateData *tunnelState = (TunnelStateData *)data; + assert (cbdataReferenceValid (tunnelState)); ++ tunnelState->server.writer = NULL; + + tunnelState->writeServerDone(buf, len, flag, xerrno); + } +@@ -575,6 +594,7 @@ + { + TunnelStateData *tunnelState = (TunnelStateData *)data; + assert (cbdataReferenceValid (tunnelState)); ++ tunnelState->client.writer = NULL; + + tunnelState->writeClientDone(buf, len, flag, xerrno); + } +@@ -592,7 +612,14 @@ + } + + void +-TunnelStateData::writeClientDone(char *buf, size_t len, comm_err_t flag, int xerrno) ++TunnelStateData::Connection::write(const char *b, int size, AsyncCall::Pointer &callback, FREE * free_func) ++{ ++ writer = callback; ++ Comm::Write(conn, b, size, callback, free_func); ++} ++ ++void ++TunnelStateData::writeClientDone(char *, size_t len, comm_err_t flag, int xerrno) + { + debugs(26, 3, HERE << client.conn << ", " << len << " bytes written, flag=" << flag); + +@@ -712,6 +739,7 @@ + { + TunnelStateData *tunnelState = (TunnelStateData *)data; + debugs(26, 3, HERE << conn << ", flag=" << flag); ++ tunnelState->client.writer = NULL; + + if (flag != COMM_OK) { + *tunnelState->status_ptr = Http::scInternalServerError; +@@ -728,6 +756,7 @@ + { + TunnelStateData *tunnelState = (TunnelStateData *)data; + debugs(26, 3, conn << ", flag=" << flag); ++ tunnelState->server.writer = NULL; + assert(tunnelState->waitingForConnectRequest()); + + if (flag != COMM_OK) { +@@ -768,7 +797,7 @@ + else { + AsyncCall::Pointer call = commCbCall(5,5, "tunnelConnectedWriteDone", + CommIoCbPtrFun(tunnelConnectedWriteDone, tunnelState)); +- Comm::Write(tunnelState->client.conn, conn_established, strlen(conn_established), call, NULL); ++ tunnelState->client.write(conn_established, strlen(conn_established), call, NULL); + } + } + +@@ -955,29 +984,20 @@ + debugs(11, 2, "Tunnel Server REQUEST: " << tunnelState->server.conn << ":\n----------\n" << + Raw("tunnelRelayConnectRequest", mb.content(), mb.contentSize()) << "\n----------"); + +- if (tunnelState->clientExpectsConnectResponse()) { +- // hack: blindly tunnel peer response (to our CONNECT request) to the client as ours. +- AsyncCall::Pointer writeCall = commCbCall(5,5, "tunnelConnectedWriteDone", +- CommIoCbPtrFun(tunnelConnectedWriteDone, tunnelState)); +- Comm::Write(srv, &mb, writeCall); +- } else { +- // we have to eat the connect response from the peer (so that the client +- // does not see it) and only then start shoveling data to the client +- AsyncCall::Pointer writeCall = commCbCall(5,5, "tunnelConnectReqWriteDone", +- CommIoCbPtrFun(tunnelConnectReqWriteDone, +- tunnelState)); +- Comm::Write(srv, &mb, writeCall); +- tunnelState->connectReqWriting = true; +- +- tunnelState->connectRespBuf = new MemBuf; +- // SQUID_TCP_SO_RCVBUF: we should not accumulate more than regular I/O buffer +- // can hold since any CONNECT response leftovers have to fit into server.buf. +- // 2*SQUID_TCP_SO_RCVBUF: HttpMsg::parse() zero-terminates, which uses space. +- tunnelState->connectRespBuf->init(SQUID_TCP_SO_RCVBUF, 2*SQUID_TCP_SO_RCVBUF); +- tunnelState->readConnectResponse(); +- +- assert(tunnelState->waitingForConnectExchange()); +- } ++ AsyncCall::Pointer writeCall = commCbCall(5,5, "tunnelConnectReqWriteDone", ++ CommIoCbPtrFun(tunnelConnectReqWriteDone, tunnelState)); ++ ++ tunnelState->server.write(mb.buf, mb.size, writeCall, mb.freeFunc()); ++ tunnelState->connectReqWriting = true; ++ ++ tunnelState->connectRespBuf = new MemBuf; ++ // SQUID_TCP_SO_RCVBUF: we should not accumulate more than regular I/O buffer ++ // can hold since any CONNECT response leftovers have to fit into server.buf. ++ // 2*SQUID_TCP_SO_RCVBUF: HttpMsg::parse() zero-terminates, which uses space. ++ tunnelState->connectRespBuf->init(SQUID_TCP_SO_RCVBUF, 2*SQUID_TCP_SO_RCVBUF); ++ tunnelState->readConnectResponse(); ++ ++ assert(tunnelState->waitingForConnectExchange()); + + AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "tunnelTimeout", + CommTimeoutCbPtrFun(tunnelTimeout, tunnelState)); + From 8c8383e55ee881651ccf201d117235b7b51b69c4 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 9 Jul 2015 12:31:32 +0200 Subject: [PATCH 7/7] Remove dnsmasq patches These are not applied any more because dnsmasq was updated to the latest release version. Signed-off-by: Michael Tremer --- ...ne-at-the-end-of-example-config-file.patch | 23 - ...-when-an-empty-suffix-is-supplied-to.patch | 86 - ...0003-Debian-build-fixes-for-kFreeBSD.patch | 36 - ...t-conntrack-mark-before-connect-call.patch | 68 - .../0005-Fix-typo-in-new-Dbus-code.patch | 26 - .../0006-Fit-example-conf-file-typo.patch | 22 - ...liance-when-unable-to-supply-address.patch | 107 - ...8-Fix-conntrack-with-bind-interfaces.patch | 39 - ...-inotify-instead-of-polling-on-Linux.patch | 257 - ...-the-new-inotify-code-about-symlinks.patch | 73 - ...oor-on-EDNS0-packet-size-with-DNSSEC.patch | 46 - .../dnsmasq/0012-CHANGELOG-re.-inotify.patch | 27 - ...eakage-of-domain-domain-subnet-local.patch | 70 - ...dundant-IN6_IS_ADDR_ULA-a-macro-defn.patch | 27 - ...rivacy-addresses-from-interface-name.patch | 148 - ...h-in-cache-dump-to-avoid-truncating-.patch | 35 - ...SEC-code-when-attempting-to-verify-l.patch | 100 - ...k-for-CNAMEs-pointing-to-A-AAAA-reco.patch | 99 - ...blems-validating-NSEC3-and-wildcards.patch | 365 - .../0020-Initialise-return-value.patch | 32 - .../0021-Add-ignore-address-option.patch | 192 - .../dnsmasq/0022-Bad-packet-protection.patch | 25 - ...d-failure-in-new-inotify-code-on-BSD.patch | 29 - ...efile-dependencies-on-COPTS-variable.patch | 68 - ...Fix-race-condition-issue-in-makefile.patch | 30 - ...wn-search-for-limit-of-secure-delega.patch | 792 - ...extra-option-for-more-complete-loggi.patch | 346 - .../0028-Add-min-cache-ttl-option.patch | 144 - ...f-requestor-when-doing-extra-logging.patch | 31 - ...m-cache-RRsets-from-wildcards-as-we-.patch | 45 - .../0031-Logs-for-DS-records-consistent.patch | 25 - ...le-interfaces-with-the-same-LL-addre.patch | 58 - ...reat-SERVFAIL-as-a-recoverable-error.patch | 25 - ...0034-Add-dhcp-hostsdir-config-option.patch | 419 - .../0035-Update-German-translation.patch | 327 - ...HCPv6-SOLICIT-messages-when-not-conf.patch | 53 - ...-be-disabled-at-compile-time-on-Linu.patch | 214 - ...ode-to-dhcp-hostsdir-dhcp-optsdir-an.patch | 562 - ...9-Update-copyrights-for-dawn-of-2015.patch | 428 - .../0040-inotify-documentation-updates.patch | 53 - ...1-Fix-broken-ECDSA-DNSSEC-signatures.patch | 39 - .../dnsmasq/0042-BSD-make-support.patch | 29 - .../0043-Fix-build-failure-on-openBSD.patch | 25 - .../dnsmasq/0044-Manpage-typo-fix.patch | 25 - ...gs-after-reading-extra-hostfiles-wit.patch | 38 - .../0046-Extra-logging-for-inotify-code.patch | 68 - src/patches/dnsmasq/0047-man-page-typo.patch | 24 - ...script-which-returned-wrong-tag-in-s.patch | 26 - src/patches/dnsmasq/0049-Typos.patch | 26 - ...c-hosts-files-work-when-no-hosts-set.patch | 45 - ...ial-memory-leaks-to-quieten-valgrind.patch | 55 - ...ialized-value-used-in-get_client_mac.patch | 27 - ...parsing-utils-in-contrib-reverse-dns.patch | 73 - ...dnssec-timestamp-option-and-facility.patch | 252 - ...to-not-crash-if-uid-changing-not-con.patch | 63 - ...6-New-version-of-contrib-reverse-dns.patch | 194 - ...estamp-code-to-create-file-later-rem.patch | 202 - ...code-for-re-running-system-calls-on-.patch | 458 - ...mple.com-equivalent-to-server-exampl.patch | 75 - ...d-interface-via-cmsg-in-unicast-repl.patch | 81 - ...C-when-a-signed-CNAME-dangles-into-a.patch | 27 - ...n-SERVFAIL-when-validation-abandoned.patch | 48 - ...tect-against-broken-DNSSEC-upstreams.patch | 37 - ...x-for-non-ascii-characters-in-labels.patch | 197 - ...aracters-in-names-in-the-cache-handl.patch | 246 - .../0066-Fix-crash-in-last-commit.patch | 30 - .../0067-Merge-message-translations.patch | 20329 --------------- ...-no-fail-to-ignore-missing-tftp-root.patch | 199 - .../dnsmasq/0069-Whitespace-fixes.patch | 85 - ...rather-than-BOGUS-when-DS-proved-not.patch | 254 - ...er-warning-when-not-including-DNSSEC.patch | 26 - ...-by-looking-up-servers.bind-when-man.patch | 54 - ...eipt-of-certain-malformed-DNS-reques.patch | 62 - ...-in-auth-code-with-odd-configuration.patch | 113 - ...replies-to-NS-and-SOA-in-.arpa-zones.patch | 106 - ...duced-crash-in-new-tftp_no_fail-code.patch | 36 - .../dnsmasq/0077-Note-CVE-2015-3294.patch | 26 - ...-reporting-DNSSEC-validation-failure.patch | 59 - ...s-command-line-arg-in-dhcp_release.c.patch | 28 - ...74c51d96fef100285a0d225824534f9-and-.patch | 53 - ...in-names-with-.-or-000-within-labels.patch | 215 - ...to-previous-DNS-label-charset-commit.patch | 136 - ...DHCPv6-not-suppressed-by-dhcp6-quiet.patch | 46 - ...on-work-when-repo-is-a-git-submodule.patch | 28 - ...er-botch-which-broke-DNSSEC-for-TCP-.patch | 40 - ...IG-RR-from-answers-to-ANY-queries-wh.patch | 29 - ...some-DHCP-lease-management-functions.patch | 57 - ...t-loss-when-fragmentation-of-large-p.patch | 332 - ...mentation-of-large-packets-is-broken.patch | 331 - ...ped-IPv6-addresses-with--stop-rebind.patch | 58 - ...pped-IPv6-addresses-with-stop-rebind.patch | 59 - .../0090-Tweak-EDNS-timeout-code.patch | 28 - ...hive-mailing-list-mirror-in-doc-html.patch | 27 - ...archive-mailing-list-mirror-in-doc.h.patch | 28 - ...w-T1-and-T2-DHCPv4-options-to-be-set.patch | 199 - .../dnsmasq/0093-Tweak-last-commit.patch | 37 - ...DHCP-context-for-PXE-proxy-server-id.patch | 29 - ...uffer-overflow-introduced-in-2-73rc6.patch | 49 - ...DHCP-context-for-PXE-proxy-server-id.patch | 29 - ...uffer-overflow-introduced-in-2.73rc6.patch | 49 - ...support-for-DNS-Extended-Label-Types.patch | 89 - ...HCP-context-when-in-PXE-bootserver-m.patch | 26 - ...098-Tweak-immediately-previous-patch.patch | 33 - src/patches/dnsmasq/0099-Man-page-typo.patch | 25 - ...dd-infiniband-to-example-config-file.patch | 30 - ...se-DNS-header-bits-in-answer-when-re.patch | 55 - ...RM-should-be-OK-for-any-address-on-l.patch | 43 - ...corner-cases-in-NSEC-coverage-checks.patch | 53 - ...ods-to-create-and-delete-DHCP-leases.patch | 329 - ...missed-logging-strings-to-the-catalo.patch | 32 - ...nknown-interface-in-bridge-interface.patch | 28 - ...-bridge-interface-aliasing-to-DHCPv6.patch | 65 - ...ertisements-to-have-the-off-link-bit.patch | 85 - ...erface-aliasing-to-solicited-router-.patch | 107 - ...erfaces-to-unsolicited-router-advert.patch | 131 - ...ates-for-bridge-interface-and-off-li.patch | 201 - ...-and-fix-makefile-process-to-do-this.patch | 21460 ---------------- ...-DS-records-when-confirming-absence-.patch | 173 - 118 files changed, 54163 deletions(-) delete mode 100644 src/patches/dnsmasq/0001-Add-newline-at-the-end-of-example-config-file.patch delete mode 100644 src/patches/dnsmasq/0002-crash-at-startup-when-an-empty-suffix-is-supplied-to.patch delete mode 100644 src/patches/dnsmasq/0003-Debian-build-fixes-for-kFreeBSD.patch delete mode 100644 src/patches/dnsmasq/0004-Set-conntrack-mark-before-connect-call.patch delete mode 100644 src/patches/dnsmasq/0005-Fix-typo-in-new-Dbus-code.patch delete mode 100644 src/patches/dnsmasq/0006-Fit-example-conf-file-typo.patch delete mode 100644 src/patches/dnsmasq/0007-Improve-RFC-compliance-when-unable-to-supply-address.patch delete mode 100644 src/patches/dnsmasq/0008-Fix-conntrack-with-bind-interfaces.patch delete mode 100644 src/patches/dnsmasq/0009-Use-inotify-instead-of-polling-on-Linux.patch delete mode 100644 src/patches/dnsmasq/0010-Teach-the-new-inotify-code-about-symlinks.patch delete mode 100644 src/patches/dnsmasq/0011-Remove-floor-on-EDNS0-packet-size-with-DNSSEC.patch delete mode 100644 src/patches/dnsmasq/0012-CHANGELOG-re.-inotify.patch delete mode 100644 src/patches/dnsmasq/0013-Fix-breakage-of-domain-domain-subnet-local.patch delete mode 100644 src/patches/dnsmasq/0014-Remove-redundant-IN6_IS_ADDR_ULA-a-macro-defn.patch delete mode 100644 src/patches/dnsmasq/0015-Eliminate-IPv6-privacy-addresses-from-interface-name.patch delete mode 100644 src/patches/dnsmasq/0016-Tweak-field-width-in-cache-dump-to-avoid-truncating-.patch delete mode 100644 src/patches/dnsmasq/0017-Fix-crash-in-DNSSEC-code-when-attempting-to-verify-l.patch delete mode 100644 src/patches/dnsmasq/0018-Make-caching-work-for-CNAMEs-pointing-to-A-AAAA-reco.patch delete mode 100644 src/patches/dnsmasq/0019-Fix-problems-validating-NSEC3-and-wildcards.patch delete mode 100644 src/patches/dnsmasq/0020-Initialise-return-value.patch delete mode 100644 src/patches/dnsmasq/0021-Add-ignore-address-option.patch delete mode 100644 src/patches/dnsmasq/0022-Bad-packet-protection.patch delete mode 100644 src/patches/dnsmasq/0023-Fix-build-failure-in-new-inotify-code-on-BSD.patch delete mode 100644 src/patches/dnsmasq/0024-Implement-makefile-dependencies-on-COPTS-variable.patch delete mode 100644 src/patches/dnsmasq/0025-Fix-race-condition-issue-in-makefile.patch delete mode 100644 src/patches/dnsmasq/0026-DNSSEC-do-top-down-search-for-limit-of-secure-delega.patch delete mode 100644 src/patches/dnsmasq/0027-Add-log-queries-extra-option-for-more-complete-loggi.patch delete mode 100644 src/patches/dnsmasq/0028-Add-min-cache-ttl-option.patch delete mode 100644 src/patches/dnsmasq/0029-Log-port-of-requestor-when-doing-extra-logging.patch delete mode 100644 src/patches/dnsmasq/0030-Don-t-answer-from-cache-RRsets-from-wildcards-as-we-.patch delete mode 100644 src/patches/dnsmasq/0031-Logs-for-DS-records-consistent.patch delete mode 100644 src/patches/dnsmasq/0032-Cope-with-multiple-interfaces-with-the-same-LL-addre.patch delete mode 100644 src/patches/dnsmasq/0033-Don-t-treat-SERVFAIL-as-a-recoverable-error.patch delete mode 100644 src/patches/dnsmasq/0034-Add-dhcp-hostsdir-config-option.patch delete mode 100644 src/patches/dnsmasq/0035-Update-German-translation.patch delete mode 100644 src/patches/dnsmasq/0036-Don-t-reply-to-DHCPv6-SOLICIT-messages-when-not-conf.patch delete mode 100644 src/patches/dnsmasq/0037-Allow-inotify-to-be-disabled-at-compile-time-on-Linu.patch delete mode 100644 src/patches/dnsmasq/0038-Expand-inotify-code-to-dhcp-hostsdir-dhcp-optsdir-an.patch delete mode 100644 src/patches/dnsmasq/0039-Update-copyrights-for-dawn-of-2015.patch delete mode 100644 src/patches/dnsmasq/0040-inotify-documentation-updates.patch delete mode 100644 src/patches/dnsmasq/0041-Fix-broken-ECDSA-DNSSEC-signatures.patch delete mode 100644 src/patches/dnsmasq/0042-BSD-make-support.patch delete mode 100644 src/patches/dnsmasq/0043-Fix-build-failure-on-openBSD.patch delete mode 100644 src/patches/dnsmasq/0044-Manpage-typo-fix.patch delete mode 100644 src/patches/dnsmasq/0045-Fixup-dhcp-configs-after-reading-extra-hostfiles-wit.patch delete mode 100644 src/patches/dnsmasq/0046-Extra-logging-for-inotify-code.patch delete mode 100644 src/patches/dnsmasq/0047-man-page-typo.patch delete mode 100644 src/patches/dnsmasq/0048-Fix-get-version-script-which-returned-wrong-tag-in-s.patch delete mode 100644 src/patches/dnsmasq/0049-Typos.patch delete mode 100644 src/patches/dnsmasq/0050-Make-dynamic-hosts-files-work-when-no-hosts-set.patch delete mode 100644 src/patches/dnsmasq/0051-Fix-trivial-memory-leaks-to-quieten-valgrind.patch delete mode 100644 src/patches/dnsmasq/0052-Fix-uninitialized-value-used-in-get_client_mac.patch delete mode 100644 src/patches/dnsmasq/0053-Log-parsing-utils-in-contrib-reverse-dns.patch delete mode 100644 src/patches/dnsmasq/0054-Add-dnssec-timestamp-option-and-facility.patch delete mode 100644 src/patches/dnsmasq/0055-Fix-last-commit-to-not-crash-if-uid-changing-not-con.patch delete mode 100644 src/patches/dnsmasq/0056-New-version-of-contrib-reverse-dns.patch delete mode 100644 src/patches/dnsmasq/0057-Tweak-DNSSEC-timestamp-code-to-create-file-later-rem.patch delete mode 100644 src/patches/dnsmasq/0058-Fix-boilerplate-code-for-re-running-system-calls-on-.patch delete mode 100644 src/patches/dnsmasq/0059-Make-address-example.com-equivalent-to-server-exampl.patch delete mode 100644 src/patches/dnsmasq/0060-dhcp-set-outbound-interface-via-cmsg-in-unicast-repl.patch delete mode 100644 src/patches/dnsmasq/0061-Don-t-fail-DNSSEC-when-a-signed-CNAME-dangles-into-a.patch delete mode 100644 src/patches/dnsmasq/0062-Return-SERVFAIL-when-validation-abandoned.patch delete mode 100644 src/patches/dnsmasq/0063-Protect-against-broken-DNSSEC-upstreams.patch delete mode 100644 src/patches/dnsmasq/0064-DNSSEC-fix-for-non-ascii-characters-in-labels.patch delete mode 100644 src/patches/dnsmasq/0065-Allow-control-characters-in-names-in-the-cache-handl.patch delete mode 100644 src/patches/dnsmasq/0066-Fix-crash-in-last-commit.patch delete mode 100644 src/patches/dnsmasq/0067-Merge-message-translations.patch delete mode 100644 src/patches/dnsmasq/0068-add-tftp-no-fail-to-ignore-missing-tftp-root.patch delete mode 100644 src/patches/dnsmasq/0069-Whitespace-fixes.patch delete mode 100644 src/patches/dnsmasq/0070-Return-INSECURE-rather-than-BOGUS-when-DS-proved-not.patch delete mode 100644 src/patches/dnsmasq/0071-Fix-compiler-warning-when-not-including-DNSSEC.patch delete mode 100644 src/patches/dnsmasq/0072-Fix-crash-caused-by-looking-up-servers.bind-when-man.patch delete mode 100644 src/patches/dnsmasq/0073-Fix-crash-on-receipt-of-certain-malformed-DNS-reques.patch delete mode 100644 src/patches/dnsmasq/0074-Fix-crash-in-auth-code-with-odd-configuration.patch delete mode 100644 src/patches/dnsmasq/0075-Auth-correct-replies-to-NS-and-SOA-in-.arpa-zones.patch delete mode 100644 src/patches/dnsmasq/0076-Fix-srk-induced-crash-in-new-tftp_no_fail-code.patch delete mode 100644 src/patches/dnsmasq/0077-Note-CVE-2015-3294.patch delete mode 100644 src/patches/dnsmasq/0078-Log-domain-when-reporting-DNSSEC-validation-failure.patch delete mode 100644 src/patches/dnsmasq/0079-Check-IP-address-command-line-arg-in-dhcp_release.c.patch delete mode 100644 src/patches/dnsmasq/0080-Revert-61b838dd574c51d96fef100285a0d225824534f9-and-.patch delete mode 100644 src/patches/dnsmasq/0081-Handle-domain-names-with-.-or-000-within-labels.patch delete mode 100644 src/patches/dnsmasq/0082-Tweaks-to-previous-DNS-label-charset-commit.patch delete mode 100644 src/patches/dnsmasq/0083-Logs-in-DHCPv6-not-suppressed-by-dhcp6-quiet.patch delete mode 100644 src/patches/dnsmasq/0084-Make-get-version-work-when-repo-is-a-git-submodule.patch delete mode 100644 src/patches/dnsmasq/0085-Fix-argument-order-botch-which-broke-DNSSEC-for-TCP-.patch delete mode 100644 src/patches/dnsmasq/0086-Don-t-remove-RRSIG-RR-from-answers-to-ANY-queries-wh.patch delete mode 100644 src/patches/dnsmasq/0087-Constify-some-DHCP-lease-management-functions.patch delete mode 100644 src/patches/dnsmasq/0088-Handle-UDP-packet-loss-when-fragmentation-of-large-p.patch delete mode 100644 src/patches/dnsmasq/0088-Handle-UDP-packet-loss-when-fragmentation-of-large-packets-is-broken.patch delete mode 100644 src/patches/dnsmasq/0089-Check-IPv4-mapped-IPv6-addresses-with--stop-rebind.patch delete mode 100644 src/patches/dnsmasq/0089-Check-IPv4-mapped-IPv6-addresses-with-stop-rebind.patch delete mode 100644 src/patches/dnsmasq/0090-Tweak-EDNS-timeout-code.patch delete mode 100644 src/patches/dnsmasq/0091-Pointer-to-mail-archive-mailing-list-mirror-in-doc-html.patch delete mode 100644 src/patches/dnsmasq/0091-Pointer-to-mail-archive-mailing-list-mirror-in-doc.h.patch delete mode 100644 src/patches/dnsmasq/0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch delete mode 100644 src/patches/dnsmasq/0093-Tweak-last-commit.patch delete mode 100644 src/patches/dnsmasq/0093-Use-correct-DHCP-context-for-PXE-proxy-server-id.patch delete mode 100644 src/patches/dnsmasq/0094-Fix-buffer-overflow-introduced-in-2-73rc6.patch delete mode 100644 src/patches/dnsmasq/0094-Use-correct-DHCP-context-for-PXE-proxy-server-id.patch delete mode 100644 src/patches/dnsmasq/0095-Fix-buffer-overflow-introduced-in-2.73rc6.patch delete mode 100644 src/patches/dnsmasq/0096-Remove-support-for-DNS-Extended-Label-Types.patch delete mode 100644 src/patches/dnsmasq/0097-Select-correct-DHCP-context-when-in-PXE-bootserver-m.patch delete mode 100644 src/patches/dnsmasq/0098-Tweak-immediately-previous-patch.patch delete mode 100644 src/patches/dnsmasq/0099-Man-page-typo.patch delete mode 100644 src/patches/dnsmasq/0100-Add-infiniband-to-example-config-file.patch delete mode 100644 src/patches/dnsmasq/0101-Correctly-sanitise-DNS-header-bits-in-answer-when-re.patch delete mode 100644 src/patches/dnsmasq/0102-DHCPv6-DHCPCONFIRM-should-be-OK-for-any-address-on-l.patch delete mode 100644 src/patches/dnsmasq/0103-Handle-corner-cases-in-NSEC-coverage-checks.patch delete mode 100644 src/patches/dnsmasq/0104-Add-Dbus-methods-to-create-and-delete-DHCP-leases.patch delete mode 100644 src/patches/dnsmasq/0105-Add-a-couple-of-missed-logging-strings-to-the-catalo.patch delete mode 100644 src/patches/dnsmasq/0106-Fix-logging-of-unknown-interface-in-bridge-interface.patch delete mode 100644 src/patches/dnsmasq/0107-Extend-bridge-interface-aliasing-to-DHCPv6.patch delete mode 100644 src/patches/dnsmasq/0108-Allow-router-advertisements-to-have-the-off-link-bit.patch delete mode 100644 src/patches/dnsmasq/0109-Upply-bridge-interface-aliasing-to-solicited-router-.patch delete mode 100644 src/patches/dnsmasq/0110-Apply-bridge-interfaces-to-unsolicited-router-advert.patch delete mode 100644 src/patches/dnsmasq/0111-Documenation-updates-for-bridge-interface-and-off-li.patch delete mode 100644 src/patches/dnsmasq/0112-Merge-messages-and-fix-makefile-process-to-do-this.patch delete mode 100644 src/patches/dnsmasq/0113-Handle-CNAMEs-to-DS-records-when-confirming-absence-.patch diff --git a/src/patches/dnsmasq/0001-Add-newline-at-the-end-of-example-config-file.patch b/src/patches/dnsmasq/0001-Add-newline-at-the-end-of-example-config-file.patch deleted file mode 100644 index 3c67b6417..000000000 --- a/src/patches/dnsmasq/0001-Add-newline-at-the-end-of-example-config-file.patch +++ /dev/null @@ -1,23 +0,0 @@ -From f2658275b25ebfe691cdcb9fede85a3088cca168 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Thu, 25 Sep 2014 21:51:25 +0100 -Subject: [PATCH 001/113] Add newline at the end of example config file. - ---- - dnsmasq.conf.example | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example -index 83924fc4a9b4..6b00bd34fbb5 100644 ---- a/dnsmasq.conf.example -+++ b/dnsmasq.conf.example -@@ -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 -\ No newline at end of file -+#conf-dir=/etc/dnsmasq.d/*.conf --- -2.1.0 - diff --git a/src/patches/dnsmasq/0002-crash-at-startup-when-an-empty-suffix-is-supplied-to.patch b/src/patches/dnsmasq/0002-crash-at-startup-when-an-empty-suffix-is-supplied-to.patch deleted file mode 100644 index 090892dd1..000000000 --- a/src/patches/dnsmasq/0002-crash-at-startup-when-an-empty-suffix-is-supplied-to.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 00cd9d551998307225312fd21f761cfa8868bd2c Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Thu, 2 Oct 2014 21:44:21 +0100 -Subject: [PATCH 002/113] crash at startup when an empty suffix is supplied to - --conf-dir - ---- - CHANGELOG | 6 ++++++ - src/option.c | 38 +++++++++++++++++++++++--------------- - 2 files changed, 29 insertions(+), 15 deletions(-) - -diff --git a/CHANGELOG b/CHANGELOG -index 768e2aaca42a..13ab41c05fc3 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -1,3 +1,9 @@ -+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. -+ -+ - version 2.72 - Add ra-advrouter mode, for RFC-3775 mobile IPv6 support. - -diff --git a/src/option.c b/src/option.c -index 45d8875fb7f9..b08e98e16f84 100644 ---- a/src/option.c -+++ b/src/option.c -@@ -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); -- } -- else -- { -- li->next = ignore_suffix; -- ignore_suffix = li; -- /* Have to copy: buffer is overwritten */ -- li->suffix = opt_string_alloc(arg); -+ 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); -+ } - } -- }; -+ } - - 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; - } - --- -2.1.0 - diff --git a/src/patches/dnsmasq/0003-Debian-build-fixes-for-kFreeBSD.patch b/src/patches/dnsmasq/0003-Debian-build-fixes-for-kFreeBSD.patch deleted file mode 100644 index 1fcb04122..000000000 --- a/src/patches/dnsmasq/0003-Debian-build-fixes-for-kFreeBSD.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 6ac3bc0452a74e16e3d620a0757b0f8caab182ec Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Fri, 3 Oct 2014 08:48:11 +0100 -Subject: [PATCH 003/113] Debian build fixes for kFreeBSD - ---- - src/tables.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/tables.c b/src/tables.c -index 834f11944cd0..dcdef794c4d2 100644 ---- a/src/tables.c -+++ b/src/tables.c -@@ -20,6 +20,10 @@ - - #if defined(HAVE_IPSET) && defined(HAVE_BSD_NETWORK) - -+#ifndef __FreeBSD__ -+#include -+#endif -+ - #include - #include - -@@ -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); --- -2.1.0 - diff --git a/src/patches/dnsmasq/0004-Set-conntrack-mark-before-connect-call.patch b/src/patches/dnsmasq/0004-Set-conntrack-mark-before-connect-call.patch deleted file mode 100644 index f734fbc85..000000000 --- a/src/patches/dnsmasq/0004-Set-conntrack-mark-before-connect-call.patch +++ /dev/null @@ -1,68 +0,0 @@ -From e9828b6f66b22ce8873f8d30a773137d1aef1b92 Mon Sep 17 00:00:00 2001 -From: Karl Vogel -Date: Fri, 3 Oct 2014 21:45:15 +0100 -Subject: [PATCH 004/113] Set conntrack mark before connect() call. - -SO_MARK has to be done before issuing the connect() call on the -TCP socket. ---- - src/forward.c | 36 ++++++++++++++++++------------------ - 1 file changed, 18 insertions(+), 18 deletions(-) - -diff --git a/src/forward.c b/src/forward.c -index 4895efeba89a..2cf29eba6e26 100644 ---- a/src/forward.c -+++ b/src/forward.c -@@ -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); --- -2.1.0 - diff --git a/src/patches/dnsmasq/0005-Fix-typo-in-new-Dbus-code.patch b/src/patches/dnsmasq/0005-Fix-typo-in-new-Dbus-code.patch deleted file mode 100644 index ef70ae3f2..000000000 --- a/src/patches/dnsmasq/0005-Fix-typo-in-new-Dbus-code.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 17b475912f6a4e72797a543dad59d4d5dde6bb1b Mon Sep 17 00:00:00 2001 -From: Daniel Collins -Date: Fri, 3 Oct 2014 21:58:43 +0100 -Subject: [PATCH 005/113] Fix typo in new Dbus code. - -Simon's fault. ---- - src/dbus.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/dbus.c b/src/dbus.c -index 15fed906bd90..a2a94dc85dac 100644 ---- a/src/dbus.c -+++ b/src/dbus.c -@@ -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); - } - --- -2.1.0 - diff --git a/src/patches/dnsmasq/0006-Fit-example-conf-file-typo.patch b/src/patches/dnsmasq/0006-Fit-example-conf-file-typo.patch deleted file mode 100644 index c6dc31e61..000000000 --- a/src/patches/dnsmasq/0006-Fit-example-conf-file-typo.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 3d9d2dd0018603a2ae4b9cd65ac6ff959f4fd8c7 Mon Sep 17 00:00:00 2001 -From: Tomas Hozza -Date: Mon, 6 Oct 2014 10:46:48 +0100 -Subject: [PATCH 006/113] Fit example conf file typo. - ---- - dnsmasq.conf.example | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example -index 6b00bd34fbb5..1bd305dbdbad 100644 ---- a/dnsmasq.conf.example -+++ b/dnsmasq.conf.example -@@ -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 --- -2.1.0 - diff --git a/src/patches/dnsmasq/0007-Improve-RFC-compliance-when-unable-to-supply-address.patch b/src/patches/dnsmasq/0007-Improve-RFC-compliance-when-unable-to-supply-address.patch deleted file mode 100644 index bc2428138..000000000 --- a/src/patches/dnsmasq/0007-Improve-RFC-compliance-when-unable-to-supply-address.patch +++ /dev/null @@ -1,107 +0,0 @@ -From b9ff5c8f435173cfa616e3c398bdc089ef690a07 Mon Sep 17 00:00:00 2001 -From: Vladislav Grishenko -Date: Mon, 6 Oct 2014 14:34:24 +0100 -Subject: [PATCH 007/113] Improve RFC-compliance when unable to supply - addresses in DHCPv6 - -While testing https://github.com/sbyx/odhcp6c client I have noticed it -permanently crashes after startup. - -The reason was it (odhcp6c) doesn't expect empty IA options in ADVERTISE -message without any suboptions. - -Despite this validation bug of odhcp6c, dnsmasq should not generate -ADVERTISE messages with IA if there's nothing to advert per RFC 3315 -17.2.2: - - 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 includes only a Status Code option with - - code NoAddrsAvail and a status message for the user, a Server - - Identifier option with the server's DUID, and a Client Identifier - - option with the client's DUID. - -Meanwhile it's need to add status code for every IA in REPLY message per -RFC3315 18.2.1: - - 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. - -So, I've changed the logic to skip IA completely from ADVERTISE messages and -to add NoAddrsAvail subcode into IA of REPLY messages. - -As for overhead, yes, I believe it's ok to return NoAddrsAvail twice in IA -and in global section for compatibility with all old and new clients. ---- - src/rfc3315.c | 27 +++++++++++++++++++++++++-- - 1 file changed, 25 insertions(+), 2 deletions(-) - -diff --git a/src/rfc3315.c b/src/rfc3315.c -index 5ebf09d50ac1..ddb390bf1136 100644 ---- a/src/rfc3315.c -+++ b/src/rfc3315.c -@@ -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); - } --- -2.1.0 - diff --git a/src/patches/dnsmasq/0008-Fix-conntrack-with-bind-interfaces.patch b/src/patches/dnsmasq/0008-Fix-conntrack-with-bind-interfaces.patch deleted file mode 100644 index 47f0ea6f5..000000000 --- a/src/patches/dnsmasq/0008-Fix-conntrack-with-bind-interfaces.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 98906275a02ae260fe3f82133bd79054f8315f06 Mon Sep 17 00:00:00 2001 -From: Hans Dedecker -Date: Tue, 9 Dec 2014 22:22:53 +0000 -Subject: [PATCH 008/113] Fix conntrack with --bind-interfaces - -Make sure dst_addr is assigned the correct address in receive_query when OPTNOWILD is -enabled so the assigned mark can be correctly retrieved and set in forward_query when -conntrack is enabled. - -Signed-off-by: Hans Dedecker ---- - src/forward.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/forward.c b/src/forward.c -index 2cf29eba6e26..408a179a20f4 100644 ---- a/src/forward.c -+++ b/src/forward.c -@@ -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; - } - } --- -2.1.0 - diff --git a/src/patches/dnsmasq/0009-Use-inotify-instead-of-polling-on-Linux.patch b/src/patches/dnsmasq/0009-Use-inotify-instead-of-polling-on-Linux.patch deleted file mode 100644 index 3cefd02fc..000000000 --- a/src/patches/dnsmasq/0009-Use-inotify-instead-of-polling-on-Linux.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 193de4abf59e49c6b70d54cfe9720fcb95ca2f71 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Wed, 10 Dec 2014 17:32:16 +0000 -Subject: [PATCH 009/113] Use inotify instead of polling on Linux. - -This should solve problems people are seeing when a file changes -twice within a second and thus is missed for polling. ---- - Makefile | 2 +- - bld/Android.mk | 2 +- - src/dnsmasq.c | 25 ++++++++++++-- - src/dnsmasq.h | 11 ++++++- - src/inotify.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 137 insertions(+), 5 deletions(-) - create mode 100644 src/inotify.c - -diff --git a/Makefile b/Makefile -index 58a7975f60b5..c340f1c7b59a 100644 ---- a/Makefile -+++ b/Makefile -@@ -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 -diff --git a/bld/Android.mk b/bld/Android.mk -index d855094eb264..d627796e8edc 100644 ---- a/bld/Android.mk -+++ b/bld/Android.mk -@@ -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 - -diff --git a/src/dnsmasq.c b/src/dnsmasq.c -index f4a89fc38183..bf2e25a55780 100644 ---- a/src/dnsmasq.c -+++ b/src/dnsmasq.c -@@ -315,9 +315,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 +799,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 +873,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 +945,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 +961,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); - -diff --git a/src/dnsmasq.h b/src/dnsmasq.h -index e74b15a5459a..ebb6b957812f 100644 ---- a/src/dnsmasq.h -+++ b/src/dnsmasq.h -@@ -541,6 +541,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 +1002,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 +1473,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 -diff --git a/src/inotify.c b/src/inotify.c -new file mode 100644 -index 000000000000..a0223443d6b6 ---- /dev/null -+++ b/src/inotify.c -@@ -0,0 +1,102 @@ -+/* 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 . -+*/ -+ -+#include "dnsmasq.h" -+#include -+ -+#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 = strrchr(res->name, '/'); -+ -+ if (!d) -+ die(_("resolv-file %s not an absolute path"), res->name, EC_MISC); -+ -+ *d = 0; /* make ->name just directory */ -+ res->wd = inotify_add_watch(daemon->inotifyfd, res->name, IN_CLOSE_WRITE | IN_MOVED_TO); -+ res->file = d+1; /* pointer to filename */ -+ -+ if (res->wd == -1 && errno == ENOENT) -+ die(_("directory %s for resolv-file is missing, cannot poll"), res->name, EC_MISC); -+ -+ *d = '/'; /* restore name */ -+ -+ 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 -+ -+ -+ --- -2.1.0 - diff --git a/src/patches/dnsmasq/0010-Teach-the-new-inotify-code-about-symlinks.patch b/src/patches/dnsmasq/0010-Teach-the-new-inotify-code-about-symlinks.patch deleted file mode 100644 index 35c405b76..000000000 --- a/src/patches/dnsmasq/0010-Teach-the-new-inotify-code-about-symlinks.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 857973e6f7e0a3d03535a9df7f9373fd7a0b65cc Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Mon, 15 Dec 2014 15:58:13 +0000 -Subject: [PATCH 010/113] Teach the new inotify code about symlinks. - ---- - src/inotify.c | 43 +++++++++++++++++++++++++++---------------- - 1 file changed, 27 insertions(+), 16 deletions(-) - -diff --git a/src/inotify.c b/src/inotify.c -index a0223443d6b6..960bf5efb41f 100644 ---- a/src/inotify.c -+++ b/src/inotify.c -@@ -41,29 +41,40 @@ void inotify_dnsmasq_init() - - inotify_buffer = safe_malloc(INOTIFY_SZ); - -- daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); - -+ 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 = strrchr(res->name, '/'); -- -- if (!d) -- die(_("resolv-file %s not an absolute path"), res->name, EC_MISC); -- -- *d = 0; /* make ->name just directory */ -- res->wd = inotify_add_watch(daemon->inotifyfd, res->name, IN_CLOSE_WRITE | IN_MOVED_TO); -- res->file = d+1; /* pointer to filename */ -- -- if (res->wd == -1 && errno == ENOENT) -- die(_("directory %s for resolv-file is missing, cannot poll"), res->name, EC_MISC); -+ char *d = NULL, *path; - -- *d = '/'; /* restore name */ -+ 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 (res->wd == -1) -- die(_("failed to create inotify for %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); -+ } - } - } - --- -2.1.0 - diff --git a/src/patches/dnsmasq/0011-Remove-floor-on-EDNS0-packet-size-with-DNSSEC.patch b/src/patches/dnsmasq/0011-Remove-floor-on-EDNS0-packet-size-with-DNSSEC.patch deleted file mode 100644 index d1766f58d..000000000 --- a/src/patches/dnsmasq/0011-Remove-floor-on-EDNS0-packet-size-with-DNSSEC.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 800c5cc1e7438818fd80f08c2d472df249a6942d Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Mon, 15 Dec 2014 17:50:15 +0000 -Subject: [PATCH 011/113] Remove floor on EDNS0 packet size with DNSSEC. - ---- - CHANGELOG | 6 +++++- - src/dnsmasq.c | 5 ----- - 2 files changed, 5 insertions(+), 6 deletions(-) - -diff --git a/CHANGELOG b/CHANGELOG -index 13ab41c05fc3..68252924e743 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -2,7 +2,11 @@ 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. -+ - - version 2.72 - Add ra-advrouter mode, for RFC-3775 mobile IPv6 support. -diff --git a/src/dnsmasq.c b/src/dnsmasq.c -index bf2e25a55780..5c7750d365fa 100644 ---- a/src/dnsmasq.c -+++ b/src/dnsmasq.c -@@ -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; --- -2.1.0 - diff --git a/src/patches/dnsmasq/0012-CHANGELOG-re.-inotify.patch b/src/patches/dnsmasq/0012-CHANGELOG-re.-inotify.patch deleted file mode 100644 index 5fe1dfb59..000000000 --- a/src/patches/dnsmasq/0012-CHANGELOG-re.-inotify.patch +++ /dev/null @@ -1,27 +0,0 @@ -From ad946d555dce44eb690c7699933b6ff40ab85bb6 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Mon, 15 Dec 2014 17:52:22 +0000 -Subject: [PATCH 012/113] CHANGELOG re. inotify. - ---- - CHANGELOG | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/CHANGELOG b/CHANGELOG -index 68252924e743..9174b0bd75dc 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -7,6 +7,10 @@ version 2.73 - 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. -+ - - version 2.72 - Add ra-advrouter mode, for RFC-3775 mobile IPv6 support. --- -2.1.0 - diff --git a/src/patches/dnsmasq/0013-Fix-breakage-of-domain-domain-subnet-local.patch b/src/patches/dnsmasq/0013-Fix-breakage-of-domain-domain-subnet-local.patch deleted file mode 100644 index 284b5cc4f..000000000 --- a/src/patches/dnsmasq/0013-Fix-breakage-of-domain-domain-subnet-local.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 3ad3f3bbd4ee716a7d2fb1e115cf89bd1b1a5de9 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Tue, 16 Dec 2014 18:25:17 +0000 -Subject: [PATCH 013/113] Fix breakage of --domain=,,local - ---- - CHANGELOG | 4 ++++ - src/option.c | 18 ++++++++++++++++-- - 2 files changed, 20 insertions(+), 2 deletions(-) - -diff --git a/CHANGELOG b/CHANGELOG -index 9174b0bd75dc..9e6c7aa4fd68 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -10,6 +10,10 @@ version 2.73 - 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=,,local - only reverse -+ queries were intercepted. THis appears to have been broken -+ since 2.69. Thanks to Josh Stone for finding the bug. - - - version 2.72 -diff --git a/src/option.c b/src/option.c -index b08e98e16f84..209fa6976609 100644 ---- a/src/option.c -+++ b/src/option.c -@@ -1941,10 +1941,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma - else - { - /* generate the equivalent of -- local=// - local=/xxx.yyy.zzz.in-addr.arpa/ */ - struct server *serv = add_rev4(new->start, msize); - serv->flags |= SERV_NO_ADDR; -+ -+ /* local=// */ -+ 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; - } - } - } -@@ -1978,10 +1985,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma - else - { - /* generate the equivalent of -- local=// - local=/xxx.yyy.zzz.ip6.arpa/ */ - struct server *serv = add_rev6(&new->start6, msize); - serv->flags |= SERV_NO_ADDR; -+ -+ /* local=// */ -+ 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; - } - } - } --- -2.1.0 - diff --git a/src/patches/dnsmasq/0014-Remove-redundant-IN6_IS_ADDR_ULA-a-macro-defn.patch b/src/patches/dnsmasq/0014-Remove-redundant-IN6_IS_ADDR_ULA-a-macro-defn.patch deleted file mode 100644 index 65030e9e4..000000000 --- a/src/patches/dnsmasq/0014-Remove-redundant-IN6_IS_ADDR_ULA-a-macro-defn.patch +++ /dev/null @@ -1,27 +0,0 @@ -From bd9520b7ade7098ee423acc38965376aa57feb07 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Tue, 16 Dec 2014 20:41:29 +0000 -Subject: [PATCH 014/113] Remove redundant IN6_IS_ADDR_ULA(a) macro defn. - ---- - src/network.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/src/network.c b/src/network.c -index 5067007c5cbc..99419f57951e 100644 ---- a/src/network.c -+++ b/src/network.c -@@ -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) --- -2.1.0 - diff --git a/src/patches/dnsmasq/0015-Eliminate-IPv6-privacy-addresses-from-interface-name.patch b/src/patches/dnsmasq/0015-Eliminate-IPv6-privacy-addresses-from-interface-name.patch deleted file mode 100644 index 8aca09fef..000000000 --- a/src/patches/dnsmasq/0015-Eliminate-IPv6-privacy-addresses-from-interface-name.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 476693678e778886b64d0b56e27eb7695cbcca99 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Wed, 17 Dec 2014 12:41:56 +0000 -Subject: [PATCH 015/113] Eliminate IPv6 privacy addresses from - --interface-name answers. - ---- - CHANGELOG | 5 +++++ - src/auth.c | 4 ++++ - src/dnsmasq.h | 1 + - src/network.c | 12 ++++++++---- - src/rfc1035.c | 17 ++++++++++------- - 5 files changed, 28 insertions(+), 11 deletions(-) - -diff --git a/CHANGELOG b/CHANGELOG -index 9e6c7aa4fd68..01f5208ec006 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -14,6 +14,11 @@ version 2.73 - Fix breakage of --domain=,,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. - - - version 2.72 -diff --git a/src/auth.c b/src/auth.c -index dd46566ec2cc..a327f16d8c0b 100644 ---- a/src/auth.c -+++ b/src/auth.c -@@ -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, -diff --git a/src/dnsmasq.h b/src/dnsmasq.h -index ebb6b957812f..1dd61c5edba3 100644 ---- a/src/dnsmasq.h -+++ b/src/dnsmasq.h -@@ -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; -diff --git a/src/network.c b/src/network.c -index 99419f57951e..14d2af2ce313 100644 ---- a/src/network.c -+++ b/src/network.c -@@ -236,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; -@@ -388,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 - } -@@ -399,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; - } -@@ -474,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; -@@ -519,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 - -diff --git a/src/rfc1035.c b/src/rfc1035.c -index 8a7d2608dac5..bdeb3fb10e68 100644 ---- a/src/rfc1035.c -+++ b/src/rfc1035.c -@@ -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) --- -2.1.0 - diff --git a/src/patches/dnsmasq/0016-Tweak-field-width-in-cache-dump-to-avoid-truncating-.patch b/src/patches/dnsmasq/0016-Tweak-field-width-in-cache-dump-to-avoid-truncating-.patch deleted file mode 100644 index df1268fcd..000000000 --- a/src/patches/dnsmasq/0016-Tweak-field-width-in-cache-dump-to-avoid-truncating-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 3267804598047bd1781cab91508d1bc516e5ddbb Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Wed, 17 Dec 2014 20:38:20 +0000 -Subject: [PATCH 016/113] Tweak field width in cache dump to avoid truncating - IPv6 addresses. - ---- - src/cache.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/cache.c b/src/cache.c -index 2c3a49887053..f9e1d31e8c99 100644 ---- a/src/cache.c -+++ b/src/cache.c -@@ -1411,7 +1411,7 @@ void dump_cache(time_t now) - *a = 0; - if (strlen(n) == 0 && !(cache->flags & F_REVERSE)) - n = ""; -- 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 +1454,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" : " ", --- -2.1.0 - diff --git a/src/patches/dnsmasq/0017-Fix-crash-in-DNSSEC-code-when-attempting-to-verify-l.patch b/src/patches/dnsmasq/0017-Fix-crash-in-DNSSEC-code-when-attempting-to-verify-l.patch deleted file mode 100644 index 81a39be30..000000000 --- a/src/patches/dnsmasq/0017-Fix-crash-in-DNSSEC-code-when-attempting-to-verify-l.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 094b5c3d904bae9aeb3206d9f3b8348926b84975 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Sun, 21 Dec 2014 16:11:52 +0000 -Subject: [PATCH 017/113] Fix crash in DNSSEC code when attempting to verify - large RRs. - ---- - CHANGELOG | 3 +++ - src/dnssec.c | 27 +++++++++++++++++++-------- - 2 files changed, 22 insertions(+), 8 deletions(-) - -diff --git a/CHANGELOG b/CHANGELOG -index 01f5208ec006..956b71a151db 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -19,6 +19,9 @@ version 2.73 - 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 -diff --git a/src/dnssec.c b/src/dnssec.c -index 69bfc29e355f..3208ac701149 100644 ---- a/src/dnssec.c -+++ b/src/dnssec.c -@@ -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; -@@ -808,7 +819,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 +827,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); --- -2.1.0 - diff --git a/src/patches/dnsmasq/0018-Make-caching-work-for-CNAMEs-pointing-to-A-AAAA-reco.patch b/src/patches/dnsmasq/0018-Make-caching-work-for-CNAMEs-pointing-to-A-AAAA-reco.patch deleted file mode 100644 index 6f41cf2e7..000000000 --- a/src/patches/dnsmasq/0018-Make-caching-work-for-CNAMEs-pointing-to-A-AAAA-reco.patch +++ /dev/null @@ -1,99 +0,0 @@ -From cbc652423403e3cef00e00240f6beef713142246 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Sun, 21 Dec 2014 21:21:53 +0000 -Subject: [PATCH 018/113] Make caching work for CNAMEs pointing to A/AAAA - records shadowed in /etc/hosts - -If the answer to an upstream query is a CNAME which points to an -A/AAAA record which also exists in /etc/hosts and friends, then -caching is suppressed, to avoid inconsistent answers. This is -now modified to allow caching when the upstream and local A/AAAA -records have the same value. ---- - src/cache.c | 34 +++++++++++++++++++++++++--------- - 1 file changed, 25 insertions(+), 9 deletions(-) - -diff --git a/src/cache.c b/src/cache.c -index f9e1d31e8c99..ff1ca6f1c352 100644 ---- a/src/cache.c -+++ b/src/cache.c -@@ -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 ,, - 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; - } --- -2.1.0 - diff --git a/src/patches/dnsmasq/0019-Fix-problems-validating-NSEC3-and-wildcards.patch b/src/patches/dnsmasq/0019-Fix-problems-validating-NSEC3-and-wildcards.patch deleted file mode 100644 index 1755c3a55..000000000 --- a/src/patches/dnsmasq/0019-Fix-problems-validating-NSEC3-and-wildcards.patch +++ /dev/null @@ -1,365 +0,0 @@ -From fbc5205702c7f6f431d9f1043c553d7fb62ddfdb Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Tue, 23 Dec 2014 15:46:08 +0000 -Subject: [PATCH 019/113] Fix problems validating NSEC3 and wildcards. - ---- - src/dnssec.c | 253 ++++++++++++++++++++++++++++++----------------------------- - 1 file changed, 128 insertions(+), 125 deletions(-) - -diff --git a/src/dnssec.c b/src/dnssec.c -index 3208ac701149..9350d3e8c963 100644 ---- a/src/dnssec.c -+++ b/src/dnssec.c -@@ -615,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. -@@ -625,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; -@@ -798,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 = '*'; - } -@@ -974,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; -@@ -1443,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; - -@@ -1520,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; - -@@ -1529,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; - -@@ -1551,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; -- } -- } -- } -- -- /* Finally, check that there's no seat of wildcard synthesis */ -- 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) -+ if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count)) - 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; -- } -- } -- } -+ /* Finally, check that there's no seat of wildcard synthesis */ -+ 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; -+ } - -- return STAT_BOGUS; -+ return STAT_SECURE; - } - - /* Validate all the RRsets in the answer and authority sections of the reply (4035:3.2.3) */ -@@ -1792,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) - { -@@ -1807,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; -@@ -1933,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. -@@ -1980,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) --- -2.1.0 - diff --git a/src/patches/dnsmasq/0020-Initialise-return-value.patch b/src/patches/dnsmasq/0020-Initialise-return-value.patch deleted file mode 100644 index 2dd2f2658..000000000 --- a/src/patches/dnsmasq/0020-Initialise-return-value.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 83d2ed09fc0216b567d7fb2197e4ff3eae150b0d Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Tue, 23 Dec 2014 18:42:38 +0000 -Subject: [PATCH 020/113] Initialise return value. - ---- - src/dnssec.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/src/dnssec.c b/src/dnssec.c -index 9350d3e8c963..ed8cf893bad2 100644 ---- a/src/dnssec.c -+++ b/src/dnssec.c -@@ -637,10 +637,13 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in - struct crec *crecp = NULL; - int type_covered, algo, labels, orig_ttl, sig_expiration, sig_inception, key_tag; - u16 *rr_desc = get_desc(type); -- -+ -+ if (wildcard_out) -+ *wildcard_out = NULL; -+ - if (!(p = skip_questions(header, plen))) - return STAT_BOGUS; -- -+ - name_labels = count_labels(name); /* For 4035 5.3.2 check */ - - /* look for RRSIGs for this RRset and get pointers to each RR in the set. */ --- -2.1.0 - diff --git a/src/patches/dnsmasq/0021-Add-ignore-address-option.patch b/src/patches/dnsmasq/0021-Add-ignore-address-option.patch deleted file mode 100644 index 7ff57afd7..000000000 --- a/src/patches/dnsmasq/0021-Add-ignore-address-option.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 32fc6dbe03569d70dd394420ceb73532cf303c33 Mon Sep 17 00:00:00 2001 -From: Glen Huang -Date: Sat, 27 Dec 2014 15:28:12 +0000 -Subject: [PATCH 021/113] Add --ignore-address option. - ---- - CHANGELOG | 8 ++++++++ - man/dnsmasq.8 | 6 ++++++ - src/dnsmasq.h | 3 ++- - src/forward.c | 4 ++++ - src/option.c | 18 +++++++++++++++--- - src/rfc1035.c | 37 +++++++++++++++++++++++++++++++++++++ - 6 files changed, 72 insertions(+), 4 deletions(-) - -diff --git a/CHANGELOG b/CHANGELOG -index 956b71a151db..2b6356bcfb02 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -22,6 +22,14 @@ version 2.73 - - Fix crash in DNSSEC code with long RRs. Thanks to Marco Davids - for the bug report. -+ -+ Add --ignore-address option. Ignore replies to A-record -+ queries which include the specified address. 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 domains, before the correct answer can -+ arrive. Thanks to Glen Huang for the patch. - - - version 2.72 -diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 -index 0b8e04f0a897..4236ba307df3 100644 ---- a/man/dnsmasq.8 -+++ b/man/dnsmasq.8 -@@ -293,6 +293,12 @@ 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 \-B, --ignore-address= -+Ignore replies to A-record queries which include the specified address. -+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. - .TP - .B \-f, --filterwin2k - Later versions of windows make periodic DNS requests which don't get sensible answers from -diff --git a/src/dnsmasq.h b/src/dnsmasq.h -index 1dd61c5edba3..7bc982ddf73c 100644 ---- a/src/dnsmasq.h -+++ b/src/dnsmasq.h -@@ -930,7 +930,7 @@ extern struct daemon { - char *runfile; - char *lease_change_command; - struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces; -- struct bogus_addr *bogus_addr; -+ struct bogus_addr *bogus_addr, *ignore_addr; - struct server *servers; - struct ipsets *ipsets; - int log_fac; /* log facility */ -@@ -1093,6 +1093,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, - time_t now, int *ad_reqd, int *do_bit); - int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, - struct bogus_addr *addr, time_t now); -+int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr); - unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, - size_t *len, unsigned char **p, int *is_sign); - int check_for_local_domain(char *name, time_t now); -diff --git a/src/forward.c b/src/forward.c -index 408a179a20f4..f28c7d51f708 100644 ---- a/src/forward.c -+++ b/src/forward.c -@@ -724,6 +724,10 @@ void reply_query(int fd, int family, time_t now) - if (!(forward = lookup_frec(ntohs(header->id), hash))) - return; - -+ if (daemon->ignore_addr && RCODE(header) == NOERROR && -+ check_for_ignored_address(header, n, daemon->ignore_addr)) -+ return; -+ - if ((RCODE(header) == SERVFAIL || RCODE(header) == REFUSED) && - !option_bool(OPT_ORDER) && - forward->forwardall == 0) -diff --git a/src/option.c b/src/option.c -index 209fa6976609..907d0cf88de9 100644 ---- a/src/option.c -+++ b/src/option.c -@@ -147,6 +147,7 @@ struct myoption { - #define LOPT_LOCAL_SERVICE 335 - #define LOPT_DNSSEC_TIME 336 - #define LOPT_LOOP_DETECT 337 -+#define LOPT_IGNORE_ADDR 338 - - #ifdef HAVE_GETOPT_LONG - static const struct option opts[] = -@@ -181,6 +182,7 @@ static const struct myoption opts[] = - { "local-service", 0, 0, LOPT_LOCAL_SERVICE }, - { "bogus-priv", 0, 0, 'b' }, - { "bogus-nxdomain", 1, 0, 'B' }, -+ { "ignore-address", 1, 0, LOPT_IGNORE_ADDR }, - { "selfmx", 0, 0, 'e' }, - { "filterwin2k", 0, 0, 'f' }, - { "pid-file", 2, 0, 'x' }, -@@ -457,6 +459,7 @@ static struct { - { LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), 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, "", gettext_noop("Ignore DNS responses containing ipaddr."), NULL }, - { 0, 0, NULL, NULL, NULL } - }; - -@@ -2119,14 +2122,23 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma - break; - - case 'B': /* --bogus-nxdomain */ -- { -+ case LOPT_IGNORE_ADDR: /* --ignore-address */ -+ { - struct in_addr addr; - unhide_metas(arg); - if (arg && (inet_pton(AF_INET, arg, &addr) > 0)) - { - struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr)); -- baddr->next = daemon->bogus_addr; -- daemon->bogus_addr = baddr; -+ if (option == 'B') -+ { -+ baddr->next = daemon->bogus_addr; -+ daemon->bogus_addr = baddr; -+ } -+ else -+ { -+ baddr->next = daemon->ignore_addr; -+ daemon->ignore_addr = baddr; -+ } - baddr->addr = addr; - } - else -diff --git a/src/rfc1035.c b/src/rfc1035.c -index bdeb3fb10e68..75c4266b47dd 100644 ---- a/src/rfc1035.c -+++ b/src/rfc1035.c -@@ -1328,6 +1328,43 @@ 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) -+{ -+ 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 */ -+ -+ for (i = ntohs(header->ancount); i != 0; i--) -+ { -+ 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; -+ } -+ -+ return 0; -+} -+ - 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, ...) - { --- -2.1.0 - diff --git a/src/patches/dnsmasq/0022-Bad-packet-protection.patch b/src/patches/dnsmasq/0022-Bad-packet-protection.patch deleted file mode 100644 index 96c4696ba..000000000 --- a/src/patches/dnsmasq/0022-Bad-packet-protection.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0b1008d367d44e77352134a4c5178f896f0db3e7 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Sat, 27 Dec 2014 15:33:32 +0000 -Subject: [PATCH 022/113] Bad packet protection. - ---- - src/dnssec.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/dnssec.c b/src/dnssec.c -index ed8cf893bad2..026794b077e5 100644 ---- a/src/dnssec.c -+++ b/src/dnssec.c -@@ -805,7 +805,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in - { - while (*name_start != '.' && *name_start != 0) - name_start++; -- if (k != 1) -+ if (k != 1 && *name_start == '.') - name_start++; - } - --- -2.1.0 - diff --git a/src/patches/dnsmasq/0023-Fix-build-failure-in-new-inotify-code-on-BSD.patch b/src/patches/dnsmasq/0023-Fix-build-failure-in-new-inotify-code-on-BSD.patch deleted file mode 100644 index f5dfad8ac..000000000 --- a/src/patches/dnsmasq/0023-Fix-build-failure-in-new-inotify-code-on-BSD.patch +++ /dev/null @@ -1,29 +0,0 @@ -From d310ab7ecbffce79d3d90debba621e0222f9bced Mon Sep 17 00:00:00 2001 -From: Matthias Andree -Date: Sat, 27 Dec 2014 15:36:38 +0000 -Subject: [PATCH 023/113] Fix build failure in new inotify code on BSD. - ---- - src/inotify.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/inotify.c b/src/inotify.c -index 960bf5efb41f..83730008c11b 100644 ---- a/src/inotify.c -+++ b/src/inotify.c -@@ -15,10 +15,10 @@ - */ - - #include "dnsmasq.h" --#include -- - #ifdef HAVE_LINUX_NETWORK - -+#include -+ - /* 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. --- -2.1.0 - diff --git a/src/patches/dnsmasq/0024-Implement-makefile-dependencies-on-COPTS-variable.patch b/src/patches/dnsmasq/0024-Implement-makefile-dependencies-on-COPTS-variable.patch deleted file mode 100644 index 6f29876c3..000000000 --- a/src/patches/dnsmasq/0024-Implement-makefile-dependencies-on-COPTS-variable.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 81c538efcebfce2ce4a1d3a420b6c885b8f08df9 Mon Sep 17 00:00:00 2001 -From: Yousong Zhou -Date: Sat, 3 Jan 2015 16:36:14 +0000 -Subject: [PATCH 024/113] Implement makefile dependencies on COPTS variable. - ---- - .gitignore | 2 +- - Makefile | 10 ++++++---- - 2 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/.gitignore b/.gitignore -index fcdbcbd135ae..23f11488ab4c 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -3,7 +3,7 @@ src/*.mo - src/dnsmasq.pot - src/dnsmasq - src/dnsmasq_baseline --src/.configured -+src/.copts_* - contrib/wrt/dhcp_lease_time - contrib/wrt/dhcp_release - debian/base/ -diff --git a/Makefile b/Makefile -index c340f1c7b59a..5675f60c2036 100644 ---- a/Makefile -+++ b/Makefile -@@ -64,6 +64,8 @@ nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG - 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` - version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"' -+copts_conf = .copts_$(shell $(CC) -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | \ -+ ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' ') - - 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 \ -@@ -83,7 +85,7 @@ all : $(BUILDDIR) - - mostly_clean : - rm -f $(BUILDDIR)/*.mo $(BUILDDIR)/*.pot -- rm -f $(BUILDDIR)/.configured $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq -+ rm -f $(BUILDDIR)/.copts_* $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq - - clean : mostly_clean - rm -f $(BUILDDIR)/dnsmasq_baseline -@@ -139,8 +141,8 @@ bloatcheck : $(BUILDDIR)/dnsmasq_baseline mostly_clean all - - # rules below are targets in recusive makes with cwd=$(BUILDDIR) - --.configured: $(hdrs) -- @rm -f *.o -+$(copts_conf): $(hdrs) -+ @rm -f *.o .copts_* - @touch $@ - - $(objs:.o=.c) $(hdrs): -@@ -149,7 +151,7 @@ $(objs:.o=.c) $(hdrs): - .c.o: - $(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $< - --dnsmasq : .configured $(hdrs) $(objs) -+dnsmasq : $(copts_conf) $(hdrs) $(objs) - $(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS) - - dnsmasq.pot : $(objs:.o=.c) $(hdrs) --- -2.1.0 - diff --git a/src/patches/dnsmasq/0025-Fix-race-condition-issue-in-makefile.patch b/src/patches/dnsmasq/0025-Fix-race-condition-issue-in-makefile.patch deleted file mode 100644 index 84245f88d..000000000 --- a/src/patches/dnsmasq/0025-Fix-race-condition-issue-in-makefile.patch +++ /dev/null @@ -1,30 +0,0 @@ -From d8dbd903d024f84a149dac2f8a674a68dfed47a3 Mon Sep 17 00:00:00 2001 -From: Yousong Zhou -Date: Mon, 5 Jan 2015 17:03:35 +0000 -Subject: [PATCH 025/113] Fix race condition issue in makefile. - ---- - Makefile | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index 5675f60c2036..bcbd5571671d 100644 ---- a/Makefile -+++ b/Makefile -@@ -148,10 +148,12 @@ $(copts_conf): $(hdrs) - $(objs:.o=.c) $(hdrs): - ln -s $(top)/$(SRC)/$@ . - -+$(objs): $(copts_conf) $(hdrs) -+ - .c.o: - $(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $< - --dnsmasq : $(copts_conf) $(hdrs) $(objs) -+dnsmasq : $(objs) - $(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS) - - dnsmasq.pot : $(objs:.o=.c) $(hdrs) --- -2.1.0 - diff --git a/src/patches/dnsmasq/0026-DNSSEC-do-top-down-search-for-limit-of-secure-delega.patch b/src/patches/dnsmasq/0026-DNSSEC-do-top-down-search-for-limit-of-secure-delega.patch deleted file mode 100644 index e715c50ae..000000000 --- a/src/patches/dnsmasq/0026-DNSSEC-do-top-down-search-for-limit-of-secure-delega.patch +++ /dev/null @@ -1,792 +0,0 @@ -From 97e618a0e3f29465acc689d87288596b006f197e Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Wed, 7 Jan 2015 21:55:43 +0000 -Subject: [PATCH 026/113] DNSSEC: do top-down search for limit of secure - delegation. - ---- - CHANGELOG | 9 ++ - src/dnsmasq.h | 11 +- - src/dnssec.c | 91 +++++++++------- - src/forward.c | 327 +++++++++++++++++++++++++++++++++------------------------- - 4 files changed, 260 insertions(+), 178 deletions(-) - -diff --git a/CHANGELOG b/CHANGELOG -index 2b6356bcfb02..e8bf80f81baa 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -31,7 +31,16 @@ version 2.73 - request for certain domains, before the correct answer can - arrive. Thanks to Glen Huang for the patch. - -+ Revisit the part of DNSSEC validation which determines if an -+ unsigned answer is legit, or is in some part of the DNS -+ tree which should be signed. Dnsmasq now works from the -+ DNS root downward looking for the limit of signed -+ delegations, rather than working bottom up. This is -+ both more correct, and less likely to trip over broken -+ nameservers in the unsigned parts of the DNS tree -+ which don't respond well to DNSSEC queries. - -+ - version 2.72 - Add ra-advrouter mode, for RFC-3775 mobile IPv6 support. - -diff --git a/src/dnsmasq.h b/src/dnsmasq.h -index 7bc982ddf73c..2f4597294a56 100644 ---- a/src/dnsmasq.h -+++ b/src/dnsmasq.h -@@ -569,8 +569,9 @@ struct hostsfile { - #define STAT_SECURE_WILDCARD 7 - #define STAT_NO_SIG 8 - #define STAT_NO_DS 9 --#define STAT_NEED_DS_NEG 10 --#define STAT_CHASE_CNAME 11 -+#define STAT_NO_NS 10 -+#define STAT_NEED_DS_NEG 11 -+#define STAT_CHASE_CNAME 12 - - #define FREC_NOREBIND 1 - #define FREC_CHECKING_DISABLED 2 -@@ -604,7 +605,9 @@ struct frec { - #ifdef HAVE_DNSSEC - int class, work_counter; - struct blockdata *stash; /* Saved reply, whilst we validate */ -- size_t stash_len; -+ struct blockdata *orig_domain; /* domain of original query, whilst -+ we're seeing is if in unsigned domain */ -+ size_t stash_len, name_start, name_len; - struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */ - struct frec *blocking_query; /* Query which is blocking us. */ - #endif -@@ -1126,7 +1129,7 @@ int in_zone(struct auth_zone *zone, char *name, char **cut); - size_t dnssec_generate_query(struct dns_header *header, char *end, char *name, int class, int type, union mysockaddr *addr); - int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t n, 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); --int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class, int *neganswer); -+int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class, int *neganswer, int *nons); - int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname); - int dnskey_keytag(int alg, int flags, unsigned char *rdata, int rdlen); - size_t filter_rrsigs(struct dns_header *header, size_t plen); -diff --git a/src/dnssec.c b/src/dnssec.c -index 026794b077e5..8f27677628b2 100644 ---- a/src/dnssec.c -+++ b/src/dnssec.c -@@ -875,8 +875,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in - /* The DNS packet is expected to contain the answer to a DNSKEY query. - Put all DNSKEYs in the answer which are valid into the cache. - return codes: -- STAT_INSECURE No DNSKEYs in reply. -- STAT_SECURE At least one valid DNSKEY found and in cache. -+ STAT_SECURE At least one valid DNSKEY found and in cache. - STAT_BOGUS No DNSKEYs found, which can be validated with DS, - or self-sign for DNSKEY RRset is not valid, bad packet. - STAT_NEED_DS DS records to validate a key not found, name in keyname -@@ -896,11 +895,8 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch - GETSHORT(qtype, p); - GETSHORT(qclass, p); - -- if (qtype != T_DNSKEY || qclass != class) -+ if (qtype != T_DNSKEY || qclass != class || ntohs(header->ancount) == 0) - return STAT_BOGUS; -- -- if (ntohs(header->ancount) == 0) -- return STAT_INSECURE; - - /* See if we have cached a DS record which validates this key */ - if (!(crecp = cache_find_by_name(NULL, name, now, F_DS))) -@@ -1103,17 +1099,17 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch - /* The DNS packet is expected to contain the answer to a DS query - Put all DSs in the answer which are valid into the cache. - return codes: -- STAT_INSECURE no DS in reply or not signed. - STAT_SECURE At least one valid DS found and in cache. - STAT_NO_DS It's proved there's no DS here. -- STAT_BOGUS At least one DS found, which fails validation, bad packet. -+ STAT_NO_NS It's proved there's no DS _or_ NS here. -+ STAT_BOGUS no DS in reply or not signed, fails validation, bad packet. - STAT_NEED_DNSKEY DNSKEY records to validate a DS not found, name in keyname - */ - - int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class) - { - unsigned char *p = (unsigned char *)(header+1); -- int qtype, qclass, val, i, neganswer; -+ int qtype, qclass, val, i, neganswer, nons; - - if (ntohs(header->qdcount) != 1 || - !(p = skip_name(p, header, plen, 4))) -@@ -1125,32 +1121,39 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char - if (qtype != T_DS || qclass != class) - val = STAT_BOGUS; - else -- val = dnssec_validate_reply(now, header, plen, name, keyname, NULL, &neganswer); -- -- if (val == STAT_NO_SIG) -- val = STAT_INSECURE; -+ val = dnssec_validate_reply(now, header, plen, name, keyname, NULL, &neganswer, &nons); -+ /* Note dnssec_validate_reply() will have cached positive answers */ -+ -+ if (val == STAT_NO_SIG || val == STAT_INSECURE) -+ val = STAT_BOGUS; - - p = (unsigned char *)(header+1); - extract_name(header, plen, &p, name, 1, 4); - p += 4; /* qtype, qclass */ - - if (!(p = skip_section(p, ntohs(header->ancount), header, plen))) -- return STAT_BOGUS; -+ val = STAT_BOGUS; - - if (val == STAT_BOGUS) -- log_query(F_UPSTREAM, name, NULL, "BOGUS DS"); -- -- if ((val == STAT_SECURE || val == STAT_INSECURE) && neganswer) - { -- int rdlen, flags = F_FORWARD | F_DS | F_NEG; -+ log_query(F_UPSTREAM, name, NULL, "BOGUS DS"); -+ return STAT_BOGUS; -+ } -+ -+ /* By here, the answer is proved secure, and a positive answer has been cached. */ -+ if (val == STAT_SECURE && neganswer) -+ { -+ int rdlen, flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK; - unsigned long ttl, minttl = ULONG_MAX; - struct all_addr a; - - if (RCODE(header) == NXDOMAIN) - flags |= F_NXDOMAIN; - -- if (val == STAT_SECURE) -- flags |= F_DNSSECOK; -+ /* We only cache validated DS records, DNSSECOK flag hijacked -+ to store presence/absence of NS. */ -+ if (nons) -+ flags &= ~F_DNSSECOK; - - for (i = ntohs(header->nscount); i != 0; i--) - { -@@ -1196,10 +1199,12 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char - a.addr.dnssec.class = class; - cache_insert(name, &a, now, ttl, flags); - -- cache_end_insert(); -+ cache_end_insert(); -+ -+ log_query(F_UPSTREAM, name, NULL, nons ? "no delegation" : "no DS"); - } - -- return (val == STAT_SECURE) ? STAT_NO_DS : STAT_INSECURE; -+ return nons ? STAT_NO_NS : STAT_NO_DS; - } - - return val; -@@ -1323,12 +1328,15 @@ static int find_nsec_records(struct dns_header *header, size_t plen, unsigned ch - } - - static int prove_non_existence_nsec(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, int *nons) - { - int i, rc, rdlen; - unsigned char *p, *psave; - int offset = (type & 0xff) >> 3; - int mask = 0x80 >> (type & 0x07); -+ -+ if (nons) -+ *nons = 0; - - /* Find NSEC record that proves name doesn't exist */ - for (i = 0; i < nsec_count; i++) -@@ -1355,6 +1363,10 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi - rdlen -= p - psave; - /* rdlen is now length of type map, and p points to it */ - -+ /* If we can prove that there's no NS record, return that information. */ -+ if (nons && rdlen >= 2 && p[0] == 0 && (p[2] & (0x80 >> T_NS)) == 0) -+ *nons = 1; -+ - while (rdlen >= 2) - { - if (!CHECK_LEN(header, p, plen, rdlen)) -@@ -1456,7 +1468,7 @@ static int base32_decode(char *in, unsigned char *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) -+ char *workspace1, char *workspace2, unsigned char **nsecs, int nsec_count, int *nons) - { - int i, hash_len, salt_len, base32_len, rdlen; - unsigned char *p, *psave; -@@ -1497,6 +1509,10 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige - if (!CHECK_LEN(header, p, plen, rdlen)) - return 0; - -+ /* If we can prove that there's no NS record, return that information. */ -+ if (nons && rdlen >= 2 && p[0] == 0 && (p[2] & (0x80 >> T_NS)) == 0) -+ *nons = 1; -+ - while (rdlen >= 2) - { - if (p[0] == type >> 8) -@@ -1533,13 +1549,16 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige - } - - 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 *wildname) -+ char *workspace1, char *workspace2, char *name, int type, char *wildname, int *nons) - { - unsigned char *salt, *p, *digest; - int digest_len, i, iterations, salt_len, base32_len, algo = 0; - struct nettle_hash const *hash; - char *closest_encloser, *next_closest, *wildcard; -- -+ -+ if (nons) -+ *nons = 0; -+ - /* Look though the NSEC3 records to find the first one with - an algorithm we support (currently only algo == 1). - -@@ -1612,7 +1631,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns - 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)) -+ if (check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count, nons)) - return STAT_SECURE; - - /* Can't find an NSEC3 which covers the name directly, we need the "closest encloser NSEC3" -@@ -1657,7 +1676,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns - if ((digest_len = hash_name(next_closest, &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)) -+ if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count, NULL)) - return STAT_BOGUS; - - /* Finally, check that there's no seat of wildcard synthesis */ -@@ -1672,7 +1691,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns - 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)) -+ if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count, NULL)) - return STAT_BOGUS; - } - -@@ -1681,7 +1700,8 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns - - /* Validate all the RRsets in the answer and authority sections of the reply (4035:3.2.3) */ - /* Returns are the same as validate_rrset, plus the class if the missing key is in *class */ --int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class, int *neganswer) -+int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, -+ int *class, int *neganswer, int *nons) - { - unsigned char *ans_start, *qname, *p1, *p2, **nsecs; - int type1, class1, rdlen1, type2, class2, rdlen2, qclass, qtype; -@@ -1811,10 +1831,11 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch - return STAT_BOGUS; /* No NSECs or bad packet */ - - if (nsec_type == T_NSEC) -- rc = prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1); -+ rc = prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1, NULL); - else -- rc = prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1, wildname); -- -+ rc = prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, -+ keyname, name, type1, wildname, NULL); -+ - if (rc != STAT_SECURE) - return rc; - } -@@ -1937,9 +1958,9 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch - return STAT_BOGUS; - - if (nsec_type == T_NSEC) -- return prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype); -+ return prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype, nons); - else -- return prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype, NULL); -+ return prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype, NULL, nons); - } - - /* Chase the CNAME chain in the packet until the first record which _doesn't validate. -diff --git a/src/forward.c b/src/forward.c -index f28c7d51f708..ee8d7b52d5e5 100644 ---- a/src/forward.c -+++ b/src/forward.c -@@ -26,8 +26,9 @@ static void free_frec(struct frec *f); - #ifdef HAVE_DNSSEC - 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 *keycount); --static int do_check_sign(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class); --static int send_check_sign(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname); -+static int do_check_sign(struct frec *forward, int status, time_t now, char *name, char *keyname); -+static int send_check_sign(struct frec *forward, time_t now, struct dns_header *header, size_t plen, -+ char *name, char *keyname); - #endif - - -@@ -815,18 +816,22 @@ void reply_query(int fd, int family, time_t now) - else if (forward->flags & FREC_DS_QUERY) - { - status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class); -- if (status == STAT_NO_DS) -- status = STAT_INSECURE; -+ if (status == STAT_NO_DS || status == STAT_NO_NS) -+ status = STAT_BOGUS; - } - else if (forward->flags & FREC_CHECK_NOSIGN) -- status = do_check_sign(now, header, n, daemon->namebuff, daemon->keyname, forward->class); -+ { -+ status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class); -+ if (status != STAT_NEED_KEY) -+ status = do_check_sign(forward, status, now, daemon->namebuff, daemon->keyname); -+ } - else - { -- status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class, NULL); -+ status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class, NULL, NULL); - if (status == STAT_NO_SIG) - { - if (option_bool(OPT_DNSSEC_NO_SIGN)) -- status = send_check_sign(now, header, n, daemon->namebuff, daemon->keyname); -+ status = send_check_sign(forward, now, header, n, daemon->namebuff, daemon->keyname); - else - status = STAT_INSECURE; - } -@@ -861,6 +866,7 @@ void reply_query(int fd, int family, time_t now) - new->blocking_query = NULL; - new->sentto = server; - new->rfd4 = NULL; -+ new->orig_domain = NULL; - #ifdef HAVE_IPV6 - new->rfd6 = NULL; - #endif -@@ -889,7 +895,9 @@ void reply_query(int fd, int family, time_t now) - new->new_id = get_id(); - header->id = htons(new->new_id); - /* Save query for retransmission */ -- new->stash = blockdata_alloc((char *)header, nn); -+ if (!(new->stash = blockdata_alloc((char *)header, nn))) -+ return; -+ - new->stash_len = nn; - - /* Don't resend this. */ -@@ -946,18 +954,22 @@ void reply_query(int fd, int family, time_t now) - else if (forward->flags & FREC_DS_QUERY) - { - status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class); -- if (status == STAT_NO_DS) -- status = STAT_INSECURE; -+ if (status == STAT_NO_DS || status == STAT_NO_NS) -+ status = STAT_BOGUS; - } - else if (forward->flags & FREC_CHECK_NOSIGN) -- status = do_check_sign(now, header, n, daemon->namebuff, daemon->keyname, forward->class); -+ { -+ status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class); -+ if (status != STAT_NEED_KEY) -+ status = do_check_sign(forward, status, now, daemon->namebuff, daemon->keyname); -+ } - else - { -- status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class, NULL); -+ status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class, NULL, NULL); - if (status == STAT_NO_SIG) - { - if (option_bool(OPT_DNSSEC_NO_SIGN)) -- status = send_check_sign(now, header, n, daemon->namebuff, daemon->keyname); -+ status = send_check_sign(forward, now, header, n, daemon->namebuff, daemon->keyname); - else - status = STAT_INSECURE; - } -@@ -1319,70 +1331,80 @@ void receive_query(struct listener *listen, time_t now) - /* UDP: we've got an unsigned answer, return STAT_INSECURE if we can prove there's no DS - and therefore the answer shouldn't be signed, or STAT_BOGUS if it should be, or - STAT_NEED_DS_NEG and keyname if we need to do the query. */ --static int send_check_sign(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname) -+static int send_check_sign(struct frec *forward, time_t now, struct dns_header *header, size_t plen, -+ char *name, char *keyname) - { -- struct crec *crecp; -- char *name_start = name; - int status = dnssec_chase_cname(now, header, plen, name, keyname); - - if (status != STAT_INSECURE) - return status; - -+ /* Store the domain we're trying to check. */ -+ forward->name_start = strlen(name); -+ forward->name_len = forward->name_start + 1; -+ if (!(forward->orig_domain = blockdata_alloc(name, forward->name_len))) -+ return STAT_BOGUS; -+ -+ return do_check_sign(forward, 0, now, name, keyname); -+} -+ -+/* We either have a a reply (header non-NULL, or we need to start by looking in the cache */ -+static int do_check_sign(struct frec *forward, int status, time_t now, char *name, char *keyname) -+{ -+ /* get domain we're checking back from blockdata store, it's stored on the original query. */ -+ while (forward->dependent) -+ forward = forward->dependent; -+ -+ blockdata_retrieve(forward->orig_domain, forward->name_len, name); -+ - while (1) - { -- crecp = cache_find_by_name(NULL, name_start, now, F_DS); -- -- if (crecp && (crecp->flags & F_DNSSECOK)) -- return (crecp->flags & F_NEG) ? STAT_INSECURE : STAT_BOGUS; -- -- if (crecp && (crecp->flags & F_NEG) && (name_start = strchr(name_start, '.'))) -+ char *p; -+ -+ if (status == 0) - { -- name_start++; /* chop a label off and try again */ -- continue; -+ struct crec *crecp; -+ -+ /* Haven't received answer, see if in cache */ -+ if (!(crecp = cache_find_by_name(NULL, &name[forward->name_start], now, F_DS))) -+ { -+ /* put name of DS record we're missing into keyname */ -+ strcpy(keyname, &name[forward->name_start]); -+ /* and wait for reply to arrive */ -+ return STAT_NEED_DS_NEG; -+ } -+ -+ /* F_DNSSECOK misused in DS cache records to non-existance of NS record */ -+ if (!(crecp->flags & F_NEG)) -+ status = STAT_SECURE; -+ else if (crecp->flags & F_DNSSECOK) -+ status = STAT_NO_DS; -+ else -+ status = STAT_NO_NS; - } -+ -+ /* Have entered non-signed part of DNS tree. */ -+ if (status == STAT_NO_DS) -+ return STAT_INSECURE; - -- /* Reached the root */ -- if (!name_start) -+ if (status == STAT_BOGUS) - return STAT_BOGUS; - -- strcpy(keyname, name_start); -- return STAT_NEED_DS_NEG; -- } --} -- --/* Got answer to DS query from send_check_sign, check for proven non-existence, or make the next DS query to try. */ --static int do_check_sign(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class) -- --{ -- char *name_start; -- unsigned char *p; -- int status; -+ /* There's a proven DS record, or we're within a zone, where there doesn't need -+ to be a DS record. Add a name and try again. -+ If we've already tried the whole name, then fail */ - -- /* In this case only, a SERVFAIL reply allows us to continue up the tree, looking for a -- suitable NSEC reply to DS queries. */ -- if (RCODE(header) != SERVFAIL) -- { -- status = dnssec_validate_ds(now, header, plen, name, keyname, class); -+ if (forward->name_start == 0) -+ return STAT_BOGUS; - -- if (status != STAT_INSECURE) -- { -- if (status == STAT_NO_DS) -- status = STAT_INSECURE; -- return status; -- } -- } -- -- p = (unsigned char *)(header+1); -- -- if (extract_name(header, plen, &p, name, 1, 4) && -- (name_start = strchr(name, '.'))) -- { -- name_start++; /* chop a label off and try again */ -- strcpy(keyname, name_start); -- return STAT_NEED_DS_NEG; -+ for (p = &name[forward->name_start-2]; (*p != '.') && (p != name); p--); -+ -+ if (p != name) -+ p++; -+ -+ forward->name_start = p - name; -+ status = 0; /* force to cache when we iterate. */ - } -- -- return STAT_BOGUS; - } - - /* Move toward the root, until we find a signed non-existance of a DS, in which case -@@ -1395,8 +1417,10 @@ static int tcp_check_for_unsigned_zone(time_t now, struct dns_header *header, s - unsigned char *packet, *payload; - u16 *length; - unsigned char *p = (unsigned char *)(header+1); -- int status; -- char *name_start = name; -+ int status, name_len; -+ struct blockdata *block; -+ -+ char *name_start; - - /* Get first insecure entry in CNAME chain */ - status = tcp_key_recurse(now, STAT_CHASE_CNAME, header, plen, class, name, keyname, server, keycount); -@@ -1409,95 +1433,113 @@ static int tcp_check_for_unsigned_zone(time_t now, struct dns_header *header, s - payload = &packet[2]; - header = (struct dns_header *)payload; - length = (u16 *)packet; -+ -+ /* Stash the name away, since the buffer will be trashed when we recurse */ -+ name_len = strlen(name) + 1; -+ name_start = name + name_len - 1; - -+ if (!(block = blockdata_alloc(name, name_len))) -+ { -+ free(packet); -+ return STAT_BOGUS; -+ } -+ - while (1) - { -- unsigned char *newhash, hash[HASH_SIZE]; - unsigned char c1, c2; -- struct crec *crecp = cache_find_by_name(NULL, name_start, now, F_DS); -- -+ struct crec *crecp; -+ - if (--(*keycount) == 0) - { - free(packet); -+ blockdata_free(block); - return STAT_BOGUS; - } -- -- if (crecp && (crecp->flags & F_DNSSECOK)) -- { -- free(packet); -- return (crecp->flags & F_NEG) ? STAT_INSECURE : STAT_BOGUS; -- } - -- /* If we have cached insecurely that a DS doesn't exist, -- ise that is a hit for where to start looking for the secure one */ -- if (crecp && (crecp->flags & F_NEG) && (name_start = strchr(name_start, '.'))) -- { -- name_start++; /* chop a label off and try again */ -- continue; -- } -- -- /* reached the root */ -- if (!name_start) -- { -- free(packet); -- return STAT_BOGUS; -+ while (crecp = cache_find_by_name(NULL, name_start, now, F_DS)) -+ { -+ if ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK)) -+ { -+ /* Found a secure denial of DS - delegation is indeed insecure */ -+ free(packet); -+ blockdata_free(block); -+ return STAT_INSECURE; -+ } -+ -+ /* Here, either there's a secure DS, or no NS and no DS, and therefore no delegation. -+ Add another label and continue. */ -+ -+ if (name_start == name) -+ { -+ free(packet); -+ blockdata_free(block); -+ return STAT_BOGUS; /* run out of labels */ -+ } -+ -+ name_start -= 2; -+ while (*name_start != '.' && name_start != name) -+ name_start--; -+ if (name_start != name) -+ name_start++; - } -+ -+ /* Can't find it in the cache, have to send a query */ - - m = dnssec_generate_query(header, ((char *) header) + 65536, name_start, class, T_DS, &server->addr); - -- /* We rely on the question section coming back unchanged, ensure it is with the hash. */ -- if ((newhash = hash_questions(header, (unsigned int)m, name))) -- { -- memcpy(hash, newhash, HASH_SIZE); -+ *length = htons(m); - -- *length = htons(m); -+ if (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)) -+ { -+ m = (c1 << 8) | c2; -+ -+ /* Note this trashes all three name workspaces */ -+ status = tcp_key_recurse(now, STAT_NEED_DS_NEG, header, m, class, name, keyname, server, keycount); - -- if (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)) -+ if (status == STAT_NO_DS) - { -- m = (c1 << 8) | c2; -- -- newhash = hash_questions(header, (unsigned int)m, name); -- if (newhash && memcmp(hash, newhash, HASH_SIZE) == 0) -- { -- /* In this case only, a SERVFAIL reply allows us to continue up the tree, looking for a -- suitable NSEC reply to DS queries. */ -- if (RCODE(header) == SERVFAIL) -- status = STAT_INSECURE; -- else -- /* Note this trashes all three name workspaces */ -- status = tcp_key_recurse(now, STAT_NEED_DS_NEG, header, m, class, name, keyname, server, keycount); -- -- /* We've found a DS which proves the bit of the DNS where the -- original query is, is unsigned, so the answer is OK, -- if unvalidated. */ -- if (status == STAT_NO_DS) -- { -- free(packet); -- return STAT_INSECURE; -- } -- -- /* No DS, not got to DNSSEC-land yet, go up. */ -- if (status == STAT_INSECURE) -- { -- p = (unsigned char *)(header+1); -- -- if (extract_name(header, plen, &p, name, 1, 4) && -- (name_start = strchr(name, '.'))) -- { -- name_start++; /* chop a label off and try again */ -- continue; -- } -- } -- } -+ /* Found a secure denial of DS - delegation is indeed insecure */ -+ free(packet); -+ blockdata_free(block); -+ return STAT_INSECURE; -+ } -+ -+ if (status == STAT_BOGUS) -+ { -+ free(packet); -+ blockdata_free(block); -+ return STAT_BOGUS; -+ } -+ -+ /* Here, either there's a secure DS, or no NS and no DS, and therefore no delegation. -+ Add another label and continue. */ -+ -+ /* Get name we're checking back. */ -+ blockdata_retrieve(block, name_len, name); -+ -+ if (name_start == name) -+ { -+ free(packet); -+ blockdata_free(block); -+ return STAT_BOGUS; /* run out of labels */ - } -+ -+ name_start -= 2; -+ while (*name_start != '.' && name_start != name) -+ name_start--; -+ if (name_start != name) -+ name_start++; -+ } -+ else -+ { -+ /* IO failure */ -+ free(packet); -+ blockdata_free(block); -+ return STAT_BOGUS; /* run out of labels */ - } -- -- free(packet); -- -- return STAT_BOGUS; - } - } - -@@ -1516,14 +1558,14 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si - else if (status == STAT_NEED_DS || status == STAT_NEED_DS_NEG) - { - new_status = dnssec_validate_ds(now, header, n, name, keyname, class); -- if (status == STAT_NEED_DS && new_status == STAT_NO_DS) -- new_status = STAT_INSECURE; -+ if (status == STAT_NEED_DS && (new_status == STAT_NO_DS || new_status == STAT_NO_NS)) -+ new_status = STAT_BOGUS; - } - else if (status == STAT_CHASE_CNAME) - new_status = dnssec_chase_cname(now, header, n, name, keyname); - else - { -- new_status = dnssec_validate_reply(now, header, n, name, keyname, &class, NULL); -+ new_status = dnssec_validate_reply(now, header, n, name, keyname, &class, NULL, NULL); - - if (new_status == STAT_NO_SIG) - { -@@ -1576,14 +1618,14 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si - else if (status == STAT_NEED_DS || status == STAT_NEED_DS_NEG) - { - new_status = dnssec_validate_ds(now, header, n, name, keyname, class); -- if (status == STAT_NEED_DS && new_status == STAT_NO_DS) -- new_status = STAT_INSECURE; /* Validated no DS */ -+ if (status == STAT_NEED_DS && (new_status == STAT_NO_DS || new_status == STAT_NO_NS)) -+ new_status = STAT_BOGUS; /* Validated no DS */ - } - else if (status == STAT_CHASE_CNAME) - new_status = dnssec_chase_cname(now, header, n, name, keyname); - else - { -- new_status = dnssec_validate_reply(now, header, n, name, keyname, &class, NULL); -+ new_status = dnssec_validate_reply(now, header, n, name, keyname, &class, NULL, NULL); - - if (new_status == STAT_NO_SIG) - { -@@ -1961,6 +2003,7 @@ static struct frec *allocate_frec(time_t now) - f->dependent = NULL; - f->blocking_query = NULL; - f->stash = NULL; -+ f->orig_domain = NULL; - #endif - daemon->frec_list = f; - } -@@ -2029,6 +2072,12 @@ static void free_frec(struct frec *f) - f->stash = NULL; - } - -+ if (f->orig_domain) -+ { -+ blockdata_free(f->orig_domain); -+ f->orig_domain = NULL; -+ } -+ - /* Anything we're waiting on is pointless now, too */ - if (f->blocking_query) - free_frec(f->blocking_query); --- -2.1.0 - diff --git a/src/patches/dnsmasq/0027-Add-log-queries-extra-option-for-more-complete-loggi.patch b/src/patches/dnsmasq/0027-Add-log-queries-extra-option-for-more-complete-loggi.patch deleted file mode 100644 index f64352714..000000000 --- a/src/patches/dnsmasq/0027-Add-log-queries-extra-option-for-more-complete-loggi.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 25cf5e373eb41c088d4ee5e625209c4cf6a5659e Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Fri, 9 Jan 2015 15:53:03 +0000 -Subject: [PATCH 027/113] Add --log-queries=extra option for more complete - logging. - ---- - CHANGELOG | 3 +++ - man/dnsmasq.8 | 5 ++++- - src/cache.c | 11 ++++++++++- - src/config.h | 1 + - src/dnsmasq.c | 5 +++++ - src/dnsmasq.h | 9 +++++++-- - src/dnssec.c | 14 +++++++------- - src/forward.c | 30 ++++++++++++++++++++++++++---- - src/option.c | 11 +++++++++-- - 9 files changed, 72 insertions(+), 17 deletions(-) - -diff --git a/CHANGELOG b/CHANGELOG -index e8bf80f81baa..0bbb7835df4f 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -40,6 +40,9 @@ version 2.73 - nameservers in the unsigned parts of the DNS tree - which don't respond well to DNSSEC queries. - -+ Add --log-queries=extra option, which makes logs easier -+ to search automatically. -+ - - version 2.72 - Add ra-advrouter mode, for RFC-3775 mobile IPv6 support. -diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 -index 4236ba307df3..227d74bd80e7 100644 ---- a/man/dnsmasq.8 -+++ b/man/dnsmasq.8 -@@ -98,7 +98,10 @@ only, to stop dnsmasq daemonising in production, use - .B -k. - .TP - .B \-q, --log-queries --Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on receipt of SIGUSR1. -+Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on receipt of SIGUSR1. If the argument "extra" is supplied, ie -+.B --log-queries=extra -+then the log has extra information at the start of each line. -+This consists of a serial number which ties together the log lines associated with an individual query, and the IP address of the requestor. - .TP - .B \-8, --log-facility= - Set the facility to which dnsmasq will send syslog entries, this -diff --git a/src/cache.c b/src/cache.c -index ff1ca6f1c352..960bb7938778 100644 ---- a/src/cache.c -+++ b/src/cache.c -@@ -1638,7 +1638,16 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg) - if (strlen(name) == 0) - name = "."; - -- my_syslog(LOG_INFO, "%s %s %s %s", source, name, verb, dest); -+ if (option_bool(OPT_EXTRALOG)) -+ { -+ prettyprint_addr(daemon->log_source_addr, daemon->addrbuff2); -+ if (flags & F_NOEXTRA) -+ my_syslog(LOG_INFO, "* %s %s %s %s %s", daemon->addrbuff2, source, name, verb, dest); -+ else -+ my_syslog(LOG_INFO, "%u %s %s %s %s %s", daemon->log_display_id, daemon->addrbuff2, source, name, verb, dest); -+ } -+ else -+ my_syslog(LOG_INFO, "%s %s %s %s", source, name, verb, dest); - } - - -diff --git a/src/config.h b/src/config.h -index 145820ad2510..3b88d8193dca 100644 ---- a/src/config.h -+++ b/src/config.h -@@ -17,6 +17,7 @@ - #define FTABSIZ 150 /* max number of outstanding requests (default) */ - #define MAX_PROCS 20 /* max no children for TCP requests */ - #define CHILD_LIFETIME 150 /* secs 'till terminated (RFC1035 suggests > 120s) */ -+#define TCP_MAX_QUERIES 100 /* Maximum number of queries per incoming TCP connection */ - #define EDNS_PKTSZ 4096 /* default max EDNS.0 UDP packet from RFC5625 */ - #define KEYBLOCK_LEN 40 /* choose to mininise fragmentation when storing DNSSEC keys */ - #define DNSSEC_WORK 50 /* Max number of queries to validate one question */ -diff --git a/src/dnsmasq.c b/src/dnsmasq.c -index 5c7750d365fa..c0c0589d4ce1 100644 ---- a/src/dnsmasq.c -+++ b/src/dnsmasq.c -@@ -93,6 +93,8 @@ int main (int argc, char **argv) - daemon->packet = safe_malloc(daemon->packet_buff_sz); - - daemon->addrbuff = safe_malloc(ADDRSTRLEN); -+ if (option_bool(OPT_EXTRALOG)) -+ daemon->addrbuff2 = safe_malloc(ADDRSTRLEN); - - #ifdef HAVE_DNSSEC - if (option_bool(OPT_DNSSEC_VALID)) -@@ -1587,6 +1589,9 @@ static void check_dns_listeners(fd_set *set, time_t now) - } - } - close(confd); -+ -+ /* The child can use up to TCP_MAX_QUERIES ids, so skip that many. */ -+ daemon->log_id += TCP_MAX_QUERIES; - } - #endif - else -diff --git a/src/dnsmasq.h b/src/dnsmasq.h -index 2f4597294a56..4e9aea401b75 100644 ---- a/src/dnsmasq.h -+++ b/src/dnsmasq.h -@@ -238,7 +238,8 @@ struct event_desc { - #define OPT_DNSSEC_NO_SIGN 48 - #define OPT_LOCAL_SERVICE 49 - #define OPT_LOOP_DETECT 50 --#define OPT_LAST 51 -+#define OPT_EXTRALOG 51 -+#define OPT_LAST 52 - - /* 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. */ -@@ -442,6 +443,7 @@ struct crec { - #define F_NO_RR (1u<<25) - #define F_IPSET (1u<<26) - #define F_NSIGMATCH (1u<<27) -+#define F_NOEXTRA (1u<<28) - - /* Values of uid in crecs with F_CONFIG bit set. */ - #define SRC_INTERFACE 0 -@@ -599,7 +601,7 @@ struct frec { - #endif - unsigned int iface; - unsigned short orig_id, new_id; -- int fd, forwardall, flags; -+ int log_id, fd, forwardall, flags; - time_t time; - unsigned char *hash[HASH_SIZE]; - #ifdef HAVE_DNSSEC -@@ -1002,6 +1004,8 @@ extern struct daemon { - struct randfd randomsocks[RANDOM_SOCKS]; - 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 */ -+ union mysockaddr *log_source_addr; - - /* DHCP state */ - int dhcpfd, helperfd, pxefd; -@@ -1033,6 +1037,7 @@ extern struct daemon { - - /* utility string buffer, hold max sized IP address as string */ - char *addrbuff; -+ char *addrbuff2; /* only allocated when OPT_EXTRALOG */ - - } *daemon; - -diff --git a/src/dnssec.c b/src/dnssec.c -index 8f27677628b2..afb3dca38cb1 100644 ---- a/src/dnssec.c -+++ b/src/dnssec.c -@@ -1038,7 +1038,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch - else - { - a.addr.keytag = keytag; -- log_query(F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %u"); -+ log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %u"); - - recp1->addr.key.keylen = rdlen - 4; - recp1->addr.key.keydata = key; -@@ -1092,7 +1092,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch - return STAT_SECURE; - } - -- log_query(F_UPSTREAM, name, NULL, "BOGUS DNSKEY"); -+ log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DNSKEY"); - return STAT_BOGUS; - } - -@@ -1136,7 +1136,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char - - if (val == STAT_BOGUS) - { -- log_query(F_UPSTREAM, name, NULL, "BOGUS DS"); -+ log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS"); - return STAT_BOGUS; - } - -@@ -1201,7 +1201,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char - - cache_end_insert(); - -- log_query(F_UPSTREAM, name, NULL, nons ? "no delegation" : "no DS"); -+ log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no delegation" : "no DS"); - } - - return nons ? STAT_NO_NS : STAT_NO_DS; -@@ -1885,7 +1885,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch - else - { - a.addr.keytag = keytag; -- log_query(F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %u"); -+ log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %u"); - crecp->addr.ds.digest = digest; - crecp->addr.ds.keydata = key; - crecp->addr.ds.algo = algo; -@@ -2058,10 +2058,10 @@ size_t dnssec_generate_query(struct dns_header *header, char *end, char *name, i - char *types = querystr("dnssec-query", type); - - if (addr->sa.sa_family == AF_INET) -- log_query(F_DNSSEC | F_IPV4, name, (struct all_addr *)&addr->in.sin_addr, types); -+ log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, name, (struct all_addr *)&addr->in.sin_addr, types); - #ifdef HAVE_IPV6 - else -- log_query(F_DNSSEC | F_IPV6, name, (struct all_addr *)&addr->in6.sin6_addr, types); -+ log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, name, (struct all_addr *)&addr->in6.sin6_addr, types); - #endif - - header->qdcount = htons(1); -diff --git a/src/forward.c b/src/forward.c -index 55f583383bc6..713a64c0fa58 100644 ---- a/src/forward.c -+++ b/src/forward.c -@@ -279,10 +279,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, - plen = forward->stash_len; - - if (forward->sentto->addr.sa.sa_family == AF_INET) -- log_query(F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec"); -+ log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec"); - #ifdef HAVE_IPV6 - else -- log_query(F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec"); -+ log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec"); - #endif - - if (forward->sentto->sfd) -@@ -389,6 +389,9 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, - struct server *firstsentto = start; - int forwarded = 0; - -+ /* If a query is retried, use the log_id for the retry when logging the answer. */ -+ forward->log_id = daemon->log_id; -+ - if (option_bool(OPT_ADD_MAC)) - plen = add_mac(header, plen, ((char *) header) + daemon->packet_buff_sz, &forward->source); - -@@ -725,6 +728,11 @@ void reply_query(int fd, int family, time_t now) - if (!(forward = lookup_frec(ntohs(header->id), hash))) - return; - -+ /* log_query gets called indirectly all over the place, so -+ pass these in global variables - sorry. */ -+ daemon->log_display_id = forward->log_id; -+ daemon->log_source_addr = &forward->source; -+ - if (daemon->ignore_addr && RCODE(header) == NOERROR && - check_for_ignored_address(header, n, daemon->ignore_addr)) - return; -@@ -1258,6 +1266,11 @@ void receive_query(struct listener *listen, time_t now) - dst_addr_4.s_addr = 0; - } - } -+ -+ /* log_query gets called indirectly all over the place, so -+ pass these in global variables - sorry. */ -+ daemon->log_display_id = ++daemon->log_id; -+ daemon->log_source_addr = &source_addr; - - if (extract_request(header, (size_t)n, daemon->namebuff, &type)) - { -@@ -1675,7 +1688,8 @@ unsigned char *tcp_request(int confd, time_t now, - struct in_addr dst_addr_4; - union mysockaddr peer_addr; - socklen_t peer_len = sizeof(union mysockaddr); -- -+ int query_count = 0; -+ - if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) == -1) - return packet; - -@@ -1712,7 +1726,8 @@ unsigned char *tcp_request(int confd, time_t now, - - while (1) - { -- if (!packet || -+ if (query_count == TCP_MAX_QUERIES || -+ !packet || - !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) || - !(size = c1 << 8 | c2) || - !read_write(confd, payload, size, 1)) -@@ -1721,6 +1736,13 @@ unsigned char *tcp_request(int confd, time_t now, - if (size < (int)sizeof(struct dns_header)) - continue; - -+ query_count++; -+ -+ /* log_query gets called indirectly all over the place, so -+ pass these in global variables - sorry. */ -+ daemon->log_display_id = ++daemon->log_id; -+ daemon->log_source_addr = &peer_addr; -+ - check_subnet = 0; - - /* save state of "cd" flag in query */ -diff --git a/src/option.c b/src/option.c -index 907d0cf88de9..b7372be0a090 100644 ---- a/src/option.c -+++ b/src/option.c -@@ -149,6 +149,7 @@ struct myoption { - #define LOPT_LOOP_DETECT 337 - #define LOPT_IGNORE_ADDR 338 - -+ - #ifdef HAVE_GETOPT_LONG - static const struct option opts[] = - #else -@@ -160,7 +161,7 @@ static const struct myoption opts[] = - { "no-poll", 0, 0, 'n' }, - { "help", 0, 0, 'w' }, - { "no-daemon", 0, 0, 'd' }, -- { "log-queries", 0, 0, 'q' }, -+ { "log-queries", 2, 0, 'q' }, - { "user", 2, 0, 'u' }, - { "group", 2, 0, 'g' }, - { "resolv-file", 2, 0, 'r' }, -@@ -357,7 +358,7 @@ static struct { - { LOPT_FORCE, ARG_DUP, "", gettext_noop("DHCP option sent even if the client does not request it."), NULL}, - { 'p', ARG_ONE, "", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL }, - { 'P', ARG_ONE, "", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" }, -- { 'q', OPT_LOG, NULL, gettext_noop("Log DNS queries."), NULL }, -+ { 'q', ARG_DUP, NULL, gettext_noop("Log DNS queries."), NULL }, - { 'Q', ARG_ONE, "", gettext_noop("Force the originating port for upstream DNS queries."), NULL }, - { 'R', OPT_NO_RESOLV, NULL, gettext_noop("Do NOT read resolv.conf."), NULL }, - { 'r', ARG_DUP, "", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE }, -@@ -2421,6 +2422,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma - ret_err(gen_err); - break; - -+ case 'q': /* --log-queries */ -+ set_option_bool(OPT_LOG); -+ if (arg && strcmp(arg, "extra") == 0) -+ set_option_bool(OPT_EXTRALOG); -+ break; -+ - case LOPT_MAX_LOGS: /* --log-async */ - daemon->max_logs = LOG_MAX; /* default */ - if (arg && !atoi_check(arg, &daemon->max_logs)) --- -2.1.0 - diff --git a/src/patches/dnsmasq/0028-Add-min-cache-ttl-option.patch b/src/patches/dnsmasq/0028-Add-min-cache-ttl-option.patch deleted file mode 100644 index 8714feb9c..000000000 --- a/src/patches/dnsmasq/0028-Add-min-cache-ttl-option.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 28de38768e2c7d763b9aa5b7a4d251d5e56bab0b Mon Sep 17 00:00:00 2001 -From: RinSatsuki -Date: Sat, 10 Jan 2015 15:22:21 +0000 -Subject: [PATCH 028/113] Add --min-cache-ttl option. - ---- - CHANGELOG | 7 +++++++ - man/dnsmasq.8 | 6 ++++++ - src/cache.c | 4 +++- - src/config.h | 1 + - src/dnsmasq.h | 2 +- - src/option.c | 11 +++++++++++ - 6 files changed, 29 insertions(+), 2 deletions(-) - -diff --git a/CHANGELOG b/CHANGELOG -index 0bbb7835df4f..23fc6d0530cf 100644 ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -43,6 +43,13 @@ version 2.73 - Add --log-queries=extra option, which makes logs easier - to search automatically. - -+ Add --min-cache-ttl option. I've resisted this for a long -+ time, on the grounds that disbelieving TTLs is never a -+ good idea, but I've been persuaded that there are -+ sometimes reasons to do it. (Step forward, GFW). -+ To avoid misuse, there's a hard limit on the TTL -+ floor of one hour. Thansk to RinSatsuki for the patch. -+ - - version 2.72 - Add ra-advrouter mode, for RFC-3775 mobile IPv6 support. -diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 -index 227d74bd80e7..5cfa355dea4a 100644 ---- a/man/dnsmasq.8 -+++ b/man/dnsmasq.8 -@@ -81,6 +81,12 @@ the upstream DNS servers. - .B --max-cache-ttl=