Skip to content

Commit

Permalink
Domain-Rule: Support configuration of dualstack selection
Browse files Browse the repository at this point in the history
  • Loading branch information
pymumu committed Jan 9, 2021
1 parent ed63c61 commit 98be18f
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 14 deletions.
2 changes: 1 addition & 1 deletion ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ https://github.com/pymumu/smartdns/releases
|nameserver|指定域名使用server组解析||nameserver /domain/[group\|-], `group`为组名,`-`表示忽略此规则,配套server中的`-group`参数使用| nameserver /www.example.com/office
|ipset|域名IPSET|None|ipset /domain/[ipset\|-], `-`表示忽略|ipset /www.example.com/pass
|ipset-timeout|设置IPSET超时功能启用|auto|[yes]|ipset-timeout yes
|domain-rules|设置域名规则||domain-rules /domain/ [-rules...]<br>`[-speed-check-mode]`: 测速模式,参考`speed-check-mode`配置<br>`[-address]`: 参考`address`配置<br>`[-nameserver]`: 参考`nameserver`配置<br>`[-ipset]`:参考`ipset`配置|domain-rules /www.example.com/ -speed-check-mode none
|domain-rules|设置域名规则||domain-rules /domain/ [-rules...]<br>`[-c\|-speed-check-mode]`: 测速模式,参考`speed-check-mode`配置<br>`[-a\|-address]`: 参考`address`配置<br>`[-n\|-nameserver]`: 参考`nameserver`配置<br>`[-p\|-ipset]`:参考`ipset`配置<br>`[-d\|-dualstack-ip-selection]`: 参考`dualstack-ip-selection`|domain-rules /www.example.com/ -speed-check-mode none
|bogus-nxdomain|假冒IP地址过滤||[ip/subnet],可重复| bogus-nxdomain 1.2.3.4/16
|ignore-ip|忽略IP地址||[ip/subnet],可重复| ignore-ip 1.2.3.4/16
|whitelist-ip|白名单IP地址||[ip/subnet],可重复| whitelist-ip 1.2.3.4/16
Expand Down
2 changes: 1 addition & 1 deletion ReadMe_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,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\|-], `-` for ignore|ipset /www.example.com/pass
|ipset-timeout|ipset timeout enable|auto|[yes]|ipset-timeout yes
|domain-rules|set domain rules|None|domain-rules /domain/ [-rules...]<br>`[-speed-check-mode]`: set speed check mode,same as parameter `speed-check-mode`<br>`[-address]`: same as parameter `address` <br>`[-nameserver]`: same as parameter `nameserver`<br>`[-ipset]`: same as parameter `ipset`|domain-rules /www.example.com/ -speed-check-mode none
|domain-rules|set domain rules|None|domain-rules /domain/ [-rules...]<br>`[-c\|-speed-check-mode]`: set speed check mode,same as parameter `speed-check-mode`<br>`[-a\|-address]`: same as parameter `address` <br>`[-n\|-nameserver]`: same as parameter `nameserver`<br>`[-p\|-ipset]`: same as parameter `ipset`<br>`[-d\|-dualstack-ip-selection]`: same as parameter `dualstack-ip-selection`|domain-rules /www.example.com/ -speed-check-mode none
|bogus-nxdomain|bogus IP address|None|[IP/subnet], Repeatable| bogus-nxdomain 1.2.3.4/16
|ignore-ip|ignore ip address|None|[ip/subnet], Repeatable| ignore-ip 1.2.3.4/16
|whitelist-ip|ip whitelist|None|[ip/subnet], Repeatable,When the filtering server responds IPs in the IP whitelist, only result in whitelist will be accepted| whitelist-ip 1.2.3.4/16
Expand Down
9 changes: 5 additions & 4 deletions etc/smartdns/smartdns.conf
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,9 @@ log-level info
# set domain rules
# domain-rules /domain/ [-speed-check-mode [...]]
# rules:
# -speed-check-mode [mode]: speed check mode
# [-c] -speed-check-mode [mode]: speed check mode
# speed-check-mode [ping|tcp:port|none|,]
# -address [address|-]: same as address option
# -nameserver [group|-]: same as nameserver option
# -ipset [ipset|-]: same as ipset option
# [-a] -address [address|-]: same as address option
# [-n] -nameserver [group|-]: same as nameserver option
# [-p] -ipset [ipset|-]: same as ipset option
# [-d] -dualstack-ip-selection [yes|no]: same as dualstack-ip-selection option
49 changes: 42 additions & 7 deletions src/dns_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ static int _config_domain_rule_add(char *domain, enum domain_rule type, void *ru
return -1;
}

static int _config_domain_rule_flag_set(char *domain, unsigned int flag)
static int _config_domain_rule_flag_set(char *domain, unsigned int flag, unsigned int is_clear)
{
struct dns_domain_rule *domain_rule = NULL;
struct dns_domain_rule *old_domain_rule = NULL;
Expand Down Expand Up @@ -521,7 +521,12 @@ static int _config_domain_rule_flag_set(char *domain, unsigned int flag)
}

rule_flags = domain_rule->rules[DOMAIN_RULE_FLAGS];
rule_flags->flags |= flag;
if (is_clear == false) {
rule_flags->flags |= flag;
} else {
rule_flags->flags &= ~flag;
}
rule_flags->is_flag_set |= flag;

/* update domain rule */
if (add_domain_rule) {
Expand Down Expand Up @@ -606,7 +611,7 @@ static int _conf_domain_rule_ipset(char *domain, const char *ipsetname)
ipset_rule->ipsetname = ipset;
} else {
/* ignore this domain */
if (_config_domain_rule_flag_set(domain, DOMAIN_FLAG_IPSET_IGNORE) != 0) {
if (_config_domain_rule_flag_set(domain, DOMAIN_FLAG_IPSET_IGNORE, 0) != 0) {
goto errout;
}

Expand Down Expand Up @@ -670,7 +675,7 @@ static int _conf_domain_rule_address(char *domain, const char *domain_address)
}

/* add SOA rule */
if (_config_domain_rule_flag_set(domain, flag) != 0) {
if (_config_domain_rule_flag_set(domain, flag, 0) != 0) {
goto errout;
}

Expand All @@ -687,7 +692,7 @@ static int _conf_domain_rule_address(char *domain, const char *domain_address)
}

/* ignore rule */
if (_config_domain_rule_flag_set(domain, flag) != 0) {
if (_config_domain_rule_flag_set(domain, flag, 0) != 0) {
goto errout;
}

Expand Down Expand Up @@ -1008,7 +1013,7 @@ static int _conf_domain_rule_nameserver(char *domain, const char *group_name)
nameserver_rule->group_name = group;
} else {
/* ignore this domain */
if (_config_domain_rule_flag_set(domain, DOMAIN_FLAG_NAMESERVER_IGNORE) != 0) {
if (_config_domain_rule_flag_set(domain, DOMAIN_FLAG_NAMESERVER_IGNORE, 0) != 0) {
goto errout;
}

Expand All @@ -1029,6 +1034,26 @@ static int _conf_domain_rule_nameserver(char *domain, const char *group_name)
return 0;
}

static int _conf_domain_rule_dualstack_selection(char *domain, const char *yesno)
{
if (strncmp(yesno, "yes", sizeof("yes")) == 0 || strncmp(yesno, "Yes", sizeof("Yes")) == 0) {
if (_config_domain_rule_flag_set(domain, DOMAIN_FLAG_DUALSTACK_SELECT, 0) != 0) {
goto errout;
}
} else {
/* ignore this domain */
if (_config_domain_rule_flag_set(domain, DOMAIN_FLAG_DUALSTACK_SELECT, 1) != 0) {
goto errout;
}
}

return 0;

errout:
tlog(TLOG_ERROR, "set dualstack for %s failed. ", domain);
return 1;
}

static int _config_nameserver(void *data, int argc, char *argv[])
{
char domain[DNS_MAX_CONF_CNAME_LEN];
Expand Down Expand Up @@ -1239,6 +1264,7 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
{"address", required_argument, NULL, 'a'},
{"ipset", required_argument, NULL, 'p'},
{"nameserver", required_argument, NULL, 'n'},
{"dualstack-ip-selection", required_argument, NULL, 'd'},
{NULL, no_argument, NULL, 0}
};
/* clang-format on */
Expand All @@ -1255,7 +1281,7 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
/* process extra options */
optind = 1;
while (1) {
opt = getopt_long_only(argc, argv, "", long_options, NULL);
opt = getopt_long_only(argc, argv, "c:a:p:n:d:", long_options, NULL);
if (opt == -1) {
break;
}
Expand Down Expand Up @@ -1313,6 +1339,15 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])

break;
}
case 'd': {
const char *yesno = optarg;
if (_conf_domain_rule_dualstack_selection(domain, yesno) != 0) {
tlog(TLOG_ERROR, "set dualstack selection rule failed.");
goto errout;
}

break;
}
default:
break;
}
Expand Down
2 changes: 2 additions & 0 deletions src/dns_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ typedef enum {
#define DOMAIN_FLAG_ADDR_IPV6_IGN (1 << 5)
#define DOMAIN_FLAG_IPSET_IGNORE (1 << 6)
#define DOMAIN_FLAG_NAMESERVER_IGNORE (1 << 7)
#define DOMAIN_FLAG_DUALSTACK_SELECT (1 << 8)

#define SERVER_FLAG_EXCLUDE_DEFAULT (1 << 0)

Expand All @@ -95,6 +96,7 @@ typedef enum {

struct dns_rule_flags {
unsigned int flags;
unsigned int is_flag_set;
};

struct dns_address_IPV4 {
Expand Down
20 changes: 19 additions & 1 deletion src/dns_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,21 @@ static int _dns_server_epoll_ctl(struct dns_server_conn_head *head, int op, uint

static void _dns_server_set_dualstack_selection(struct dns_request *request)
{
struct dns_rule_flags *rule_flag = NULL;

rule_flag = request->domain_rule.rules[DOMAIN_RULE_FLAGS];
if (rule_flag) {
if (rule_flag->flags & DOMAIN_FLAG_DUALSTACK_SELECT) {
request->dualstack_selection = 1;
return;
}

if (rule_flag->is_flag_set & DOMAIN_FLAG_DUALSTACK_SELECT) {
request->dualstack_selection = 0;
return;
}
}

if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_DUALSTACK_SELECTION) == 0) {
request->dualstack_selection = 0;
return;
Expand Down Expand Up @@ -2591,6 +2606,10 @@ static int _dns_server_do_query(struct dns_request *request, const char *domain,
group_name = dns_group;
}

_dns_server_set_dualstack_selection(request);

tlog(TLOG_DEBUG, "dualstack selection %d", request->dualstack_selection);

if (_dns_server_process_special_query(request) == 0) {
goto clean_exit;
}
Expand Down Expand Up @@ -2717,7 +2736,6 @@ static int _dns_server_recv(struct dns_server_conn_head *conn, unsigned char *in
_dns_server_request_set_client(request, conn);
_dns_server_request_set_client_addr(request, from, from_len);
_dns_server_request_set_id(request, packet->head.id);
_dns_server_set_dualstack_selection(request);
ret = _dns_server_do_query(request, domain, qtype);
if (ret != 0) {
tlog(TLOG_ERROR, "do query %s failed.\n", domain);
Expand Down

0 comments on commit 98be18f

Please sign in to comment.