Initial commit
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled
Build all core packages / Build all core packages for selected target (push) Has been cancelled
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
Build Toolchains / Build Toolchains for each target (push) Has been cancelled
Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
Coverity scan build / Coverity x86/64 build (push) Has been cancelled

This commit is contained in:
domenico
2025-06-24 12:51:15 +02:00
commit 27c9d80f51
10493 changed files with 1885777 additions and 0 deletions

View File

@@ -0,0 +1,204 @@
#
# Copyright (C) 2006-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmasq
PKG_UPSTREAM_VERSION:=2.90
PKG_VERSION:=$(subst test,~~test,$(subst rc,~rc,$(PKG_UPSTREAM_VERSION)))
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_UPSTREAM_VERSION).tar.xz
PKG_SOURCE_URL:=https://thekelleys.org.uk/dnsmasq/
PKG_HASH:=8e50309bd837bfec9649a812e066c09b6988b73d749b7d293c06c57d46a109e4
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
PKG_CPE_ID:=cpe:/a:thekelleys:dnsmasq
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_UPSTREAM_VERSION)
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=lto
PKG_ASLR_PIE_REGULAR:=1
PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcp \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcpv6 \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dnssec \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_auth \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_nftset \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_conntrack \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_noid \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_broken_rtc \
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_tftp
include $(INCLUDE_DIR)/package.mk
define Package/dnsmasq/Default
SECTION:=net
CATEGORY:=Base system
TITLE:=DNS and DHCP server
URL:=http://www.thekelleys.org.uk/dnsmasq/
DEPENDS:=+libubus
USERID:=dnsmasq=453:dnsmasq=453
endef
define Package/dnsmasq
$(call Package/dnsmasq/Default)
VARIANT:=nodhcpv6
endef
define Package/dnsmasq-dhcpv6
$(call Package/dnsmasq/Default)
TITLE += (with DHCPv6 support)
DEPENDS+=@IPV6
VARIANT:=dhcpv6
PROVIDES:=dnsmasq
endef
define Package/dnsmasq-full
$(call Package/dnsmasq/Default)
TITLE += (with DNSSEC, DHCPv6, Auth DNS, IPset, Nftset, Conntrack, NO_ID enabled by default)
DEPENDS+=+PACKAGE_dnsmasq_full_dnssec:libnettle \
+PACKAGE_dnsmasq_full_ipset:kmod-ipt-ipset \
+PACKAGE_dnsmasq_full_conntrack:libnetfilter-conntrack \
+PACKAGE_dnsmasq_full_nftset:nftables-json
VARIANT:=full
PROVIDES:=dnsmasq
endef
define Package/dnsmasq/description
It is intended to provide coupled DNS and DHCP service to a LAN.
endef
define Package/dnsmasq-dhcpv6/description
$(call Package/dnsmasq/description)
This is a variant with DHCPv6 support
endef
define Package/dnsmasq-full/description
$(call Package/dnsmasq/description)
This is a fully configurable variant with DHCPv4, DHCPv6, DNSSEC, Authoritative DNS
and nftset, Conntrack support & NO_ID enabled by default.
endef
define Package/dnsmasq/conffiles
/etc/config/dhcp
/etc/dnsmasq.conf
/etc/dnsmasq.d/
endef
define Package/dnsmasq-full/config
if PACKAGE_dnsmasq-full
config PACKAGE_dnsmasq_full_dhcp
bool "Build with DHCP support."
default y
config PACKAGE_dnsmasq_full_dhcpv6
bool "Build with DHCPv6 support."
depends on IPV6 && PACKAGE_dnsmasq_full_dhcp
default y
config PACKAGE_dnsmasq_full_dnssec
bool "Build with DNSSEC support."
default y
config PACKAGE_dnsmasq_full_auth
bool "Build with the facility to act as an authoritative DNS server."
default y
config PACKAGE_dnsmasq_full_ipset
bool "Build with IPset support."
default n
config PACKAGE_dnsmasq_full_nftset
bool "Build with Nftset support."
default y
config PACKAGE_dnsmasq_full_conntrack
bool "Build with Conntrack support."
default y
config PACKAGE_dnsmasq_full_noid
bool "Build with NO_ID. (hide *.bind pseudo domain)"
default y
config PACKAGE_dnsmasq_full_broken_rtc
bool "Build with HAVE_BROKEN_RTC."
default n
config PACKAGE_dnsmasq_full_tftp
bool "Build with TFTP server support."
default y
endif
endef
Package/dnsmasq-dhcpv6/conffiles = $(Package/dnsmasq/conffiles)
Package/dnsmasq-full/conffiles = $(Package/dnsmasq/conffiles)
COPTS = -DHAVE_UBUS -DHAVE_POLL_H \
$(if $(CONFIG_IPV6),,-DNO_IPV6)
ifeq ($(BUILD_VARIANT),nodhcpv6)
COPTS += -DNO_DHCP6
endif
ifeq ($(BUILD_VARIANT),full)
COPTS += $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcp),,-DNO_DHCP) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcpv6),,-DNO_DHCP6) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dnssec),-DHAVE_DNSSEC) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_auth),,-DNO_AUTH) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset),,-DNO_IPSET) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_nftset),-DHAVE_NFTSET,) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_conntrack),-DHAVE_CONNTRACK,) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_noid),-DNO_ID,) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_broken_rtc),-DHAVE_BROKEN_RTC) \
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_tftp),,-DNO_TFTP)
COPTS += $(if $(CONFIG_LIBNETTLE_MINI),-DNO_GMP,)
else
COPTS += -DNO_AUTH -DNO_IPSET -DNO_ID
endif
MAKE_FLAGS := \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
COPTS="$(COPTS)" \
PREFIX="/usr"
define Package/dnsmasq/install
$(INSTALL_DIR) $(1)/usr/sbin
$(CP) $(PKG_INSTALL_DIR)/usr/sbin/dnsmasq $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/dhcp.conf $(1)/etc/config/dhcp
$(INSTALL_CONF) ./files/dnsmasq.conf $(1)/etc/dnsmasq.conf
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/dnsmasq.init $(1)/etc/init.d/dnsmasq
$(INSTALL_DIR) $(1)/etc/hotplug.d/dhcp
$(INSTALL_DIR) $(1)/etc/hotplug.d/neigh
$(INSTALL_DIR) $(1)/etc/hotplug.d/ntp
$(INSTALL_DIR) $(1)/etc/hotplug.d/tftp
$(INSTALL_DATA) ./files/dnsmasqsec.hotplug $(1)/etc/hotplug.d/ntp/25-dnsmasqsec
$(INSTALL_DIR) $(1)/usr/share/dnsmasq
$(INSTALL_CONF) ./files/dhcpbogushostname.conf $(1)/usr/share/dnsmasq/
$(INSTALL_CONF) ./files/rfc6761.conf $(1)/usr/share/dnsmasq/
$(INSTALL_DIR) $(1)/usr/lib/dnsmasq
$(INSTALL_BIN) ./files/dhcp-script.sh $(1)/usr/lib/dnsmasq/dhcp-script.sh
$(INSTALL_DIR) $(1)/usr/share/acl.d
$(INSTALL_DATA) ./files/dnsmasq_acl.json $(1)/usr/share/acl.d/
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/50-dnsmasq-migrate-resolv-conf-auto.sh $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/50-dnsmasq-migrate-ipset.sh $(1)/etc/uci-defaults
endef
Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install)
define Package/dnsmasq-full/install
$(call Package/dnsmasq/install,$(1))
ifneq ($(CONFIG_PACKAGE_dnsmasq_full_dnssec),)
$(INSTALL_DIR) $(1)/usr/share/dnsmasq
$(INSTALL_CONF) $(PKG_BUILD_DIR)/trust-anchors.conf $(1)/usr/share/dnsmasq
endif
endef
$(eval $(call BuildPackage,dnsmasq))
$(eval $(call BuildPackage,dnsmasq-dhcpv6))
$(eval $(call BuildPackage,dnsmasq-full))

View File

@@ -0,0 +1,32 @@
#!/bin/sh
ipsets=$(uci -q get dhcp.@dnsmasq[0].ipset)
[ -z "$ipsets" ] && exit 0
for ipset in $ipsets; do
names=${ipset##*/}
domains=${ipset%/*}
[ -z "$names" ] || [ -z "$domains" ] && continue
uci add dhcp ipset
OLDIFS="$IFS"
IFS=","
for name in $names; do
uci add_list dhcp.@ipset[-1].name="$name"
done
IFS="/"
for domain in ${domains:1}; do
uci add_list dhcp.@ipset[-1].domain="$domain"
done
IFS="$OLDIFS"
uci del_list dhcp.@dnsmasq[0].ipset="$ipset"
done
uci commit dhcp
exit 0

View File

@@ -0,0 +1,8 @@
#!/bin/sh
[ "$(uci get dhcp.@dnsmasq[0].resolvfile)" = "/tmp/resolv.conf.auto" ] && {
uci set dhcp.@dnsmasq[0].resolvfile="/tmp/resolv.conf.d/resolv.conf.auto"
uci commit dhcp
}
exit 0

View File

@@ -0,0 +1,53 @@
#!/bin/sh
[ -f "$USER_DHCPSCRIPT" ] && . "$USER_DHCPSCRIPT" "$@"
. /usr/share/libubox/jshn.sh
json_init
json_add_array env
hotplugobj=""
case "$1" in
add | del | old | arp-add | arp-del)
json_add_string "" "MACADDR=$2"
json_add_string "" "IPADDR=$3"
;;
esac
case "$1" in
add)
json_add_string "" "ACTION=add"
json_add_string "" "HOSTNAME=$4"
hotplugobj="dhcp"
;;
del)
json_add_string "" "ACTION=remove"
json_add_string "" "HOSTNAME=$4"
hotplugobj="dhcp"
;;
old)
json_add_string "" "ACTION=update"
json_add_string "" "HOSTNAME=$4"
hotplugobj="dhcp"
;;
arp-add)
json_add_string "" "ACTION=add"
hotplugobj="neigh"
;;
arp-del)
json_add_string "" "ACTION=remove"
hotplugobj="neigh"
;;
tftp)
json_add_string "" "ACTION=add"
json_add_string "" "TFTP_SIZE=$2"
json_add_string "" "TFTP_ADDR=$3"
json_add_string "" "TFTP_PATH=$4"
hotplugobj="tftp"
;;
esac
json_close_array env
[ -n "$hotplugobj" ] && ubus call hotplug.${hotplugobj} call "$(json_dump)"

View File

@@ -0,0 +1,37 @@
config dnsmasq
option domainneeded 1
option boguspriv 1
option filterwin2k 0 # enable for dial on demand
option localise_queries 1
option rebind_protection 1 # disable if upstream must serve RFC1918 addresses
option rebind_localhost 1 # enable for RBL checking and similar services
#list rebind_domain example.lan # whitelist RFC1918 responses for domains
option local '/lan/'
option domain 'lan'
option expandhosts 1
option nonegcache 0
option cachesize 1000
option authoritative 1
option readethers 1
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
#list server '/mycompany.local/1.2.3.4'
option nonwildcard 1 # bind to & keep track of interfaces
#list interface br-lan
#list notinterface lo
#list bogusnxdomain '64.94.110.11'
option localservice 1 # disable to allow DNS requests from non-local subnets
option ednspacket_max 1232
option filter_aaaa 0
option filter_a 0
#list addnmount /some/path # read-only mount path to expose it to dnsmasq
config dhcp lan
option interface lan
option start 100
option limit 150
option leasetime 12h
config dhcp wan
option interface wan
option ignore 1

View File

@@ -0,0 +1,8 @@
# dhcpbogushostname.conf included configuration file for dnsmasq
#
# includes a list of hostnames that should not be associated with dhcp leases
# in response to CERT VU#598349
# file included by default, option dhcpbogushostname 0 to disable
dhcp-name-match=set:dhcp_bogus_hostname,localhost
dhcp-name-match=set:dhcp_bogus_hostname,wpad

View File

@@ -0,0 +1,37 @@
# Change the following lines if you want dnsmasq to serve SRV
# records.
# You may add multiple srv-host lines.
# The fields are <name>,<target>,<port>,<priority>,<weight>
# A SRV record sending LDAP for the example.com domain to
# ldapserver.example.com port 289
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389
# Two SRV records for LDAP, each with different priorities
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2
# A SRV record indicating that there is no LDAP server for the domain
# example.com
#srv-host=_ldap._tcp.example.com
# The following line shows how to make dnsmasq serve an arbitrary PTR
# record. This is useful for DNS-SD.
# The fields are <name>,<target>
#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services"
# Change the following lines to enable dnsmasq to serve TXT records.
# These are used for things like SPF and zeroconf.
# The fields are <name>,<text>,<text>...
#Example SPF.
#txt-record=example.com,"v=spf1 a -all"
#Example zeroconf
#txt-record=_http._tcp.example.com,name=value,paper=A4
# Provide an alias for a "local" DNS name. Note that this _only_ works
# for targets which are names from DHCP or /etc/hosts. Give host
# "bert" another name, bertrand
# The fields are <cname>,<target>
#cname=bertand,bert

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
{
"user": "dnsmasq",
"publish": [ "dnsmasq" ],
"access": {
"hotplug.dhcp": {
"methods": [ "call" ]
},
"hotplug.neigh": {
"methods": [ "call" ]
},
"hotplug.tftp": {
"methods": [ "call" ]
}
}
}

View File

@@ -0,0 +1,12 @@
TIMEVALIDFILE="/var/state/dnsmasqsec"
[ "$ACTION" = "stratum" ] || exit 0
[ -f "$TIMEVALIDFILE" ] || {
echo "ntpd says time is valid" >$TIMEVALIDFILE
/etc/init.d/dnsmasq enabled && {
initscript=dnsmasq
. /lib/functions/procd.sh
procd_send_signal dnsmasq '*' INT
}
}

View File

@@ -0,0 +1,11 @@
# RFC6761 included configuration file for dnsmasq
#
# includes a list of domains that should not be forwarded to Internet name servers
# to reduce burden on them, asking questions that they won't know the answer to.
server=/bind/
server=/invalid/
server=/local/
server=/localhost/
server=/onion/
server=/test/

View File

@@ -0,0 +1,43 @@
From 1ed783b8d7343c42910a61f12a8fc6237eb80417 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 19 Feb 2024 12:22:43 +0000
Subject: Fix spurious "resource limit exceeded" messages.
Replies from upstream with a REFUSED rcode can result in
log messages stating that a resource limit has been exceeded,
which is not the case.
Thanks to Dominik Derigs and the Pi-hole project for
spotting this.
---
CHANGELOG | 5 +++++
src/forward.c | 6 +++---
2 files changed, 8 insertions(+), 3 deletions(-)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+version 2.91
+ Fix spurious "resource limit exceeded messages". Thanks to
+ Dominik Derigs for the bug report.
+
+
version 2.90
Fix reversion in --rev-server introduced in 2.88 which
caused breakage if the prefix length is not exactly divisible
--- a/src/forward.c
+++ b/src/forward.c
@@ -937,10 +937,10 @@ static void dnssec_validate(struct frec
status = dnssec_validate_reply(now, header, plen, daemon->namebuff, daemon->keyname, &forward->class,
!option_bool(OPT_DNSSEC_IGN_NS) && (forward->sentto->flags & SERV_DO_DNSSEC),
NULL, NULL, NULL, &orig->validate_counter);
- }
- if (STAT_ISEQUAL(status, STAT_ABANDONED))
- log_resource = 1;
+ if (STAT_ISEQUAL(status, STAT_ABANDONED))
+ log_resource = 1;
+ }
/* Can't validate, as we're missing key data. Put this
answer aside, whilst we get that. */

View File

@@ -0,0 +1,31 @@
From ccff85ad72d2f858d9743d40525128e4f62d41a8 Mon Sep 17 00:00:00 2001
From: renmingshuai <renmingshuai@huawei.com>
Date: Wed, 21 Feb 2024 00:24:25 +0000
Subject: [PATCH] Fix error introduced in
51471cafa5a4fa44d6fe490885d9910bd72a5907
Signed-off-by: renmingshuai <renmingshuai@huawei.com>
---
src/dnssec.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/src/dnssec.c
+++ b/src/dnssec.c
@@ -1547,7 +1547,7 @@ static int prove_non_existence_nsec3(str
nsecs[i] = NULL; /* Speculative, will be restored if OK. */
if (!(p = skip_name(nsec3p, header, plen, 15)))
- return 0; /* bad packet */
+ return DNSSEC_FAIL_BADPACKET; /* bad packet */
p += 10; /* type, class, TTL, rdlen */
@@ -1640,7 +1640,7 @@ static int prove_non_existence_nsec3(str
if (!wildname)
{
if (!(wildcard = strchr(next_closest, '.')) || wildcard == next_closest)
- return 0;
+ return DNSSEC_FAIL_NONSEC;
wildcard--;
*wildcard = '*';

View File

@@ -0,0 +1,165 @@
From 02fbe60e1c7e74d2ba57109575e7bfc238b1b5d4 Mon Sep 17 00:00:00 2001
From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Date: Sun, 5 Apr 2020 17:18:23 +0100
Subject: [PATCH] drop runtime old kernel support
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
---
src/dnsmasq.c | 4 ----
src/dnsmasq.h | 5 +---
src/ipset.c | 64 ++++-----------------------------------------------
src/util.c | 19 ---------------
4 files changed, 5 insertions(+), 87 deletions(-)
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -105,10 +105,6 @@ int main (int argc, char **argv)
read_opts(argc, argv, compile_opts);
-#ifdef HAVE_LINUX_NETWORK
- daemon->kernel_version = kernel_version();
-#endif
-
if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = PACKETSZ;
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1277,7 +1277,7 @@ extern struct daemon {
int inotifyfd;
#endif
#if defined(HAVE_LINUX_NETWORK)
- int netlinkfd, kernel_version;
+ int netlinkfd;
#elif defined(HAVE_BSD_NETWORK)
int dhcp_raw_fd, dhcp_icmp_fd, routefd;
#endif
@@ -1491,9 +1491,6 @@ int read_write(int fd, unsigned char *pa
void close_fds(long max_fd, int spare1, int spare2, int spare3);
int wildcard_match(const char* wildcard, const char* match);
int wildcard_matchn(const char* wildcard, const char* match, int num);
-#ifdef HAVE_LINUX_NETWORK
-int kernel_version(void);
-#endif
/* log.c */
void die(char *message, char *arg1, int exit_code) ATTRIBUTE_NORETURN;
--- a/src/ipset.c
+++ b/src/ipset.c
@@ -70,7 +70,7 @@ struct my_nfgenmsg {
#define NL_ALIGN(len) (((len)+3) & ~(3))
static const struct sockaddr_nl snl = { .nl_family = AF_NETLINK };
-static int ipset_sock, old_kernel;
+static int ipset_sock;
static char *buffer;
static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
@@ -85,12 +85,7 @@ static inline void add_attr(struct nlmsg
void ipset_init(void)
{
- old_kernel = (daemon->kernel_version < KERNEL_VERSION(2,6,32));
-
- if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1)
- return;
-
- if (!old_kernel &&
+ if (
(buffer = safe_malloc(BUFF_SZ)) &&
(ipset_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER)) != -1 &&
(bind(ipset_sock, (struct sockaddr *)&snl, sizeof(snl)) != -1))
@@ -147,65 +142,14 @@ static int new_add_to_ipset(const char *
return errno == 0 ? 0 : -1;
}
-
-static int old_add_to_ipset(const char *setname, const union all_addr *ipaddr, int remove)
-{
- socklen_t size;
- struct ip_set_req_adt_get {
- unsigned op;
- unsigned version;
- union {
- char name[IPSET_MAXNAMELEN];
- uint16_t index;
- } set;
- char typename[IPSET_MAXNAMELEN];
- } req_adt_get;
- struct ip_set_req_adt {
- unsigned op;
- uint16_t index;
- uint32_t ip;
- } req_adt;
-
- if (strlen(setname) >= sizeof(req_adt_get.set.name))
- {
- errno = ENAMETOOLONG;
- return -1;
- }
-
- req_adt_get.op = 0x10;
- req_adt_get.version = 3;
- strcpy(req_adt_get.set.name, setname);
- size = sizeof(req_adt_get);
- if (getsockopt(ipset_sock, SOL_IP, 83, &req_adt_get, &size) < 0)
- return -1;
- req_adt.op = remove ? 0x102 : 0x101;
- req_adt.index = req_adt_get.set.index;
- req_adt.ip = ntohl(ipaddr->addr4.s_addr);
- if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0)
- return -1;
-
- return 0;
-}
-
-
-
int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove)
{
int ret = 0, af = AF_INET;
if (flags & F_IPV6)
- {
af = AF_INET6;
- /* old method only supports IPv4 */
- if (old_kernel)
- {
- errno = EAFNOSUPPORT ;
- ret = -1;
- }
- }
-
- if (ret != -1)
- ret = old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
+
+ ret = new_add_to_ipset(setname, ipaddr, af, remove);
if (ret == -1)
my_syslog(LOG_ERR, _("failed to update ipset %s: %s"), setname, strerror(errno));
--- a/src/util.c
+++ b/src/util.c
@@ -866,22 +866,3 @@ int wildcard_matchn(const char* wildcard
return (!num) || (*wildcard == *match);
}
-
-#ifdef HAVE_LINUX_NETWORK
-int kernel_version(void)
-{
- struct utsname utsname;
- int version;
- char *split;
-
- if (uname(&utsname) < 0)
- die(_("failed to find kernel version: %s"), NULL, EC_MISC);
-
- split = strtok(utsname.release, ".");
- version = (split ? atoi(split) : 0);
- split = strtok(NULL, ".");
- version = version * 256 + (split ? atoi(split) : 0);
- split = strtok(NULL, ".");
- return version * 256 + (split ? atoi(split) : 0);
-}
-#endif

View File

@@ -0,0 +1,278 @@
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -2021,6 +2021,10 @@ static void check_dns_listeners(time_t n
daemon->pipe_to_parent = pipefd[1];
}
+#ifdef HAVE_UBUS
+ drop_ubus_listeners();
+#endif
+
/* start with no upstream connections. */
for (s = daemon->servers; s; s = s->next)
s->tcpfd = -1;
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1670,14 +1670,26 @@ void emit_dbus_signal(int action, struct
/* ubus.c */
#ifdef HAVE_UBUS
+struct blob_attr;
+typedef void (*ubus_dns_notify_cb)(struct blob_attr *msg, void *priv);
+
char *ubus_init(void);
void set_ubus_listeners(void);
void check_ubus_listeners(void);
+void drop_ubus_listeners(void);
+int ubus_dns_notify_has_subscribers(void);
+struct blob_buf *ubus_dns_notify_prepare(void);
+int ubus_dns_notify(const char *type, ubus_dns_notify_cb cb, void *priv);
void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface);
# ifdef HAVE_CONNTRACK
void ubus_event_bcast_connmark_allowlist_refused(u32 mark, const char *name);
void ubus_event_bcast_connmark_allowlist_resolved(u32 mark, const char *pattern, const char *ip, u32 ttl);
# endif
+#else
+static inline int ubus_dns_notify_has_subscribers(void)
+{
+ return 0;
+}
#endif
/* ipset.c */
--- a/src/forward.c
+++ b/src/forward.c
@@ -803,7 +803,7 @@ static size_t process_reply(struct dns_h
cache_secure = 0;
}
- if (daemon->doctors && do_doctor(header, n, daemon->namebuff))
+ if ((daemon->doctors || ubus_dns_notify_has_subscribers()) && do_doctor(header, n, daemon->namebuff))
cache_secure = 0;
/* check_for_bogus_wildcard() does it's own caching, so
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -13,8 +13,10 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
#include "dnsmasq.h"
+#ifdef HAVE_UBUS
+#include <libubox/blobmsg.h>
+#endif
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
char *name, int isExtract, int extrabytes)
@@ -384,10 +386,65 @@ static int private_net6(struct in6_addr
((u32 *)a)[0] == htonl(0x20010db8); /* RFC 6303 4.6 */
}
+#ifdef HAVE_UBUS
+static void ubus_dns_doctor_cb(struct blob_attr *msg, void *priv)
+{
+ static const struct blobmsg_policy policy = {
+ .name = "address",
+ .type = BLOBMSG_TYPE_STRING,
+ };
+ struct blob_attr *val;
+ char **dest = priv;
+
+ blobmsg_parse(&policy, 1, &val, blobmsg_data(msg), blobmsg_data_len(msg));
+ if (val)
+ *dest = blobmsg_get_string(val);
+}
+
+static int ubus_dns_doctor(const char *name, int ttl, void *p, int af)
+{
+ struct blob_buf *b;
+ char *addr;
+
+ if (!name)
+ return 0;
+
+ b = ubus_dns_notify_prepare();
+ if (!b)
+ return 0;
+
+ blobmsg_add_string(b, "name", name);
+
+ blobmsg_add_u32(b, "ttl", ttl);
+
+ blobmsg_add_string(b, "type", af == AF_INET6 ? "AAAA" : "A");
+
+ addr = blobmsg_alloc_string_buffer(b, "address", INET6_ADDRSTRLEN);
+ if (!addr)
+ return 0;
+
+ inet_ntop(af, p, addr, INET6_ADDRSTRLEN);
+ blobmsg_add_string_buffer(b);
+
+ addr = NULL;
+ ubus_dns_notify("dns_result", ubus_dns_doctor_cb, &addr);
+
+ if (!addr)
+ return 0;
+
+ return inet_pton(af, addr, p) == 1;
+}
+#else
+static int ubus_dns_doctor(const char *name, int ttl, void *p, int af)
+{
+ return 0;
+}
+#endif
+
int do_doctor(struct dns_header *header, size_t qlen, char *namebuff)
{
unsigned char *p;
- int i, qtype, qclass, rdlen;
+ int i, qtype, qclass, rdlen, ttl;
int done = 0;
if (!(p = skip_questions(header, qlen)))
@@ -404,7 +461,7 @@ int do_doctor(struct dns_header *header,
GETSHORT(qtype, p);
GETSHORT(qclass, p);
- p += 4; /* ttl */
+ GETLONG(ttl, p); /* ttl */
GETSHORT(rdlen, p);
if (qclass == C_IN && qtype == T_A)
@@ -415,6 +472,9 @@ int do_doctor(struct dns_header *header,
if (!CHECK_LEN(header, p, qlen, INADDRSZ))
return done;
+ if (ubus_dns_doctor(daemon->namebuff, ttl, p, AF_INET))
+ header->hb3 &= ~HB3_AA;
+
/* alignment */
memcpy(&addr.addr4, p, INADDRSZ);
@@ -444,6 +504,14 @@ int do_doctor(struct dns_header *header,
break;
}
}
+ else if (qclass == C_IN && qtype == T_AAAA)
+ {
+ if (!CHECK_LEN(header, p, qlen, IN6ADDRSZ))
+ return 0;
+
+ if (ubus_dns_doctor(daemon->namebuff, ttl, p, AF_INET6))
+ header->hb3 &= ~HB3_AA;
+ }
if (!ADD_RDLEN(header, p, qlen, rdlen))
return done; /* bad packet */
--- a/src/ubus.c
+++ b/src/ubus.c
@@ -72,6 +72,13 @@ static struct ubus_object ubus_object =
.subscribe_cb = ubus_subscribe_cb,
};
+static struct ubus_object_type ubus_dns_object_type =
+ { .name = "dnsmasq.dns" };
+
+static struct ubus_object ubus_dns_object = {
+ .type = &ubus_dns_object_type,
+};
+
static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
{
(void)ctx;
@@ -105,13 +112,21 @@ static void ubus_disconnect_cb(struct ub
char *ubus_init()
{
struct ubus_context *ubus = NULL;
+ char *dns_name;
int ret = 0;
if (!(ubus = ubus_connect(NULL)))
return NULL;
+ dns_name = whine_malloc(strlen(daemon->ubus_name) + 5);
+ sprintf(dns_name, "%s.dns", daemon->ubus_name);
+
ubus_object.name = daemon->ubus_name;
+ ubus_dns_object.name = dns_name;
+
ret = ubus_add_object(ubus, &ubus_object);
+ if (!ret)
+ ret = ubus_add_object(ubus, &ubus_dns_object);
if (ret)
{
ubus_destroy(ubus);
@@ -181,6 +196,17 @@ void check_ubus_listeners()
} \
} while (0)
+void drop_ubus_listeners()
+{
+ struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
+
+ if (!ubus)
+ return;
+
+ ubus_free(ubus);
+ daemon->ubus = NULL;
+}
+
static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
@@ -328,6 +354,53 @@ fail:
} \
} while (0)
+int ubus_dns_notify_has_subscribers(void)
+{
+ return (daemon->ubus && ubus_dns_object.has_subscribers);
+}
+
+struct blob_buf *ubus_dns_notify_prepare(void)
+{
+ if (!ubus_dns_notify_has_subscribers())
+ return NULL;
+
+ blob_buf_init(&b, 0);
+ return &b;
+}
+
+struct ubus_dns_notify_req {
+ struct ubus_notify_request req;
+ ubus_dns_notify_cb cb;
+ void *priv;
+};
+
+static void dns_notify_cb(struct ubus_notify_request *req, int type, struct blob_attr *msg)
+{
+ struct ubus_dns_notify_req *dreq = container_of(req, struct ubus_dns_notify_req, req);
+
+ dreq->cb(msg, dreq->priv);
+}
+
+int ubus_dns_notify(const char *type, ubus_dns_notify_cb cb, void *priv)
+{
+ struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
+ struct ubus_dns_notify_req dreq;
+ int ret;
+
+ if (!ubus || !ubus_dns_object.has_subscribers)
+ return 0;
+
+ ret = ubus_notify_async(ubus, &ubus_dns_object, type, b.head, &dreq.req);
+ if (ret)
+ return ret;
+
+ dreq.req.data_cb = dns_notify_cb;
+ dreq.cb = cb;
+ dreq.priv = priv;
+
+ return ubus_complete_request(ubus, &dreq.req.req, 100);
+}
+
void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
{
struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;