From ad4c2144da034701cb957ae682b784ad0e73b4ef Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Sat, 19 Nov 2022 19:28:27 +0800 Subject: [PATCH] nftset: fix nft option ignore flag not working issue --- ReadMe.md | 2 +- ReadMe_en.md | 2 +- src/dns_conf.c | 46 +++++++++++++++++++++++++++------------------- src/dns_server.c | 8 ++++++++ 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 1ed1838..3e00e68 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -546,7 +546,7 @@ entware|ipkg update
ipkg install smartdns|软件源路径:https://bin.entw | nameserver | 指定域名使用 server 组解析 | 无 | nameserver /domain/[group\|-], group 为组名,- 表示忽略此规则,配套 server 中的 -group 参数使用 | nameserver /www.example.com/office | | ipset | 域名 ipset | 无 | ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]],-表示忽略 | ipset /www.example.com/#4:dns4,#6:- | | ipset-timeout | 设置 ipset 超时功能启用 | no | [yes\|no] | ipset-timeout yes | -| nftset | 域名 nftset | 无 | nftset /domain/#[4\|6]:[family#nftable#nftset\|-][,#[4\|6]:[family#nftable#nftset\|-]]],-表示忽略;ipv4 地址的 family 只支持 inet 和 ip;ipv6 地址的 family 只支持 inet 和 ip6;由于 nft 限制,两种地址只能分开存放于两个 set 中。| nftset /www.example.com/#4:inet#mytab#dns4,#6:- | +| nftset | 域名 nftset | 无 | nftset /domain/[#4\|#6\|-]:[family#nftable#nftset\|-][,#[4\|6]:[family#nftable#nftset\|-]]],-表示忽略;ipv4 地址的 family 只支持 inet 和 ip;ipv6 地址的 family 只支持 inet 和 ip6;由于 nft 限制,两种地址只能分开存放于两个 set 中。| nftset /www.example.com/#4:inet#mytab#dns4,#6:- | | nftset-timeout | 设置 nftset 超时功能启用 | no | [yes\|no] | nftset-timeout yes | | nftset-debug | 设置 nftset 调试功能启用 | no | [yes\|no] | nftset-debug yes | | domain-rules | 设置域名规则 | 无 | domain-rules /domain/ [-rules...]
[-c\|-speed-check-mode]:测速模式,参考 speed-check-mode 配置
[-a\|-address]:参考 address 配置
[-n\|-nameserver]:参考 nameserver 配置
[-p\|-ipset]:参考ipset配置
[-t\|-nftset]:参考nftset配置
[-d\|-dualstack-ip-selection]:参考 dualstack-ip-selection | domain-rules /www.example.com/ -speed-check-mode none | diff --git a/ReadMe_en.md b/ReadMe_en.md index 9098abc..b100412 100644 --- a/ReadMe_en.md +++ b/ReadMe_en.md @@ -505,7 +505,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use |nameserver|To query domain with specific server group|None|nameserver /domain/[group\|-], `group` is the group name, `-` means ignore this rule, use the `-group` parameter in the related server|nameserver /www.example.com/office |ipset|Domain IPSet|None|ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]], `-` for ignore|ipset /www.example.com/#4:dns4,#6:- |ipset-timeout|ipset timeout enable|no|[yes\|no]|ipset-timeout yes -|nftset|Domain nftset|None|nftset /domain/#[4\|6]:[family#nftable#nftset\|-][,#[4\|6]:[family#nftable#nftset\|-]]], `-` to ignore; the valid families are inet and ip for ipv4 addresses while the valid ones are inet and ip6 for ipv6 addresses; due to the limitation of nft, two types of addresses have to be stored in two sets|nftset /www.example.com/#4:inet#mytab#dns4,#6:- +|nftset|Domain nftset|None|nftset /domain/[#4\|#6\|-]:[family#nftable#nftset\|-][,#[4\|6]:[family#nftable#nftset\|-]]], `-` to ignore; the valid families are inet and ip for ipv4 addresses while the valid ones are inet and ip6 for ipv6 addresses; due to the limitation of nft, two types of addresses have to be stored in two sets|nftset /www.example.com/#4:inet#mytab#dns4,#6:- |nftset-timeout|nftset timeout enable|no|[yes\|no]|nftset-timeout yes |nftset-debug|nftset debug enable|no|[yes\|no]|nftset-debug yes |domain-rules|set domain rules|None|domain-rules /domain/ [-rules...]
`[-c\|-speed-check-mode]`: set speed check mode,same as parameter `speed-check-mode`
`[-a\|-address]`: same as parameter `address`
`[-n\|-nameserver]`: same as parameter `nameserver`
`[-p\|-ipset]`: same as parameter `nftset`
`[-t\|-nftset]`: same as parameter `nftset`
`[-d\|-dualstack-ip-selection]`: same as parameter `dualstack-ip-selection`|domain-rules /www.example.com/ -speed-check-mode none diff --git a/src/dns_conf.c b/src/dns_conf.c index c52bddc..f8455b4 100644 --- a/src/dns_conf.c +++ b/src/dns_conf.c @@ -930,6 +930,7 @@ static int _conf_domain_rule_nftset(char *domain, const char *nftsetname) int ignore_flag = 0; char *setname = NULL; char *tablename = NULL; + char *family = NULL; copied_name = strdup(nftsetname); @@ -938,39 +939,47 @@ static int _conf_domain_rule_nftset(char *domain, const char *nftsetname) } for (char *tok = strtok(copied_name, ","); tok; tok = strtok(NULL, ",")) { - if (tok[0] == '#') { - if (strncmp(tok, "#6:inet#", 8U) == 0 || strncmp(tok, "#6:ip6#", 7U) == 0) { - type = DOMAIN_RULE_NFTSET_IP6; - ignore_flag = DOMAIN_FLAG_NFTSET_IP6_IGN; - } else if (strncmp(tok, "#4:inet#", 4U) == 0 || strncmp(tok, "#4:ip#", 6U) == 0) { - type = DOMAIN_RULE_NFTSET_IP; - ignore_flag = DOMAIN_FLAG_NFTSET_IP_IGN; - } else { - goto errout; - } - tok += 3; + char *saveptr = NULL; + char *tok_set = NULL; + nftset_rule = NULL; + + if (strncmp(tok, "#4:", 3U) == 0) { + type = DOMAIN_RULE_NFTSET_IP; + ignore_flag = DOMAIN_FLAG_NFTSET_IP_IGN; + } else if (strncmp(tok, "#6:", 3U) == 0) { + type = DOMAIN_RULE_NFTSET_IP6; + ignore_flag = DOMAIN_FLAG_NFTSET_IP6_IGN; + } else if (strncmp(tok, "-", 2U) == 0) { + _config_domain_rule_flag_set(domain, DOMAIN_FLAG_NFTSET_INET_IGN, 0); + continue; } else { goto errout; } - if (strncmp(tok, "-", 1U) == 0) { + tok_set = tok + 3; + + if (strncmp(tok_set, "-", 2U) == 0) { _config_domain_rule_flag_set(domain, ignore_flag, 0); continue; } - tablename = strpbrk(tok, "#"); + family = strtok_r(tok_set, "#", &saveptr); + if (family == NULL) { + goto errout; + } + + tablename = strtok_r(NULL, "#", &saveptr); if (tablename == NULL) { goto errout; } - *tablename++ = '\0'; - setname = strpbrk(tablename, "#"); + + setname = strtok_r(NULL, "#", &saveptr); if (setname == NULL) { goto errout; } - *setname++ = '\0'; /* new ipset domain */ - nftset = _dns_conf_get_nftable(tok, tablename, setname); + nftset = _dns_conf_get_nftable(family, tablename, setname); if (nftset == NULL) { goto errout; } @@ -988,13 +997,12 @@ static int _conf_domain_rule_nftset(char *domain, const char *nftsetname) goto errout; } _dns_rule_put(&nftset_rule->head); - nftset_rule = NULL; } goto clear; errout: - tlog(TLOG_ERROR, "add nftset %s failed", nftsetname); + tlog(TLOG_ERROR, "add nftset %s %s failed", domain, nftsetname); if (nftset_rule) { _dns_rule_put(&nftset_rule->head); diff --git a/src/dns_server.c b/src/dns_server.c index f4edafd..eaa18b2 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -3398,6 +3398,14 @@ static void _dns_server_update_rule_by_flags(struct dns_request *request) request->domain_rule.rules[DOMAIN_RULE_IPSET_IPV6] = NULL; } + if (flags & DOMAIN_FLAG_NFTSET_IP_IGN || flags & DOMAIN_FLAG_NFTSET_INET_IGN) { + request->domain_rule.rules[DOMAIN_RULE_NFTSET_IP] = NULL; + } + + if (flags & DOMAIN_FLAG_NFTSET_IP6_IGN || flags & DOMAIN_FLAG_NFTSET_INET_IGN) { + request->domain_rule.rules[DOMAIN_RULE_NFTSET_IP6] = NULL; + } + if (flags & DOMAIN_FLAG_NAMESERVER_IGNORE) { request->domain_rule.rules[DOMAIN_RULE_NAMESERVER] = NULL; }