Domain-Rule: Support configuration of dualstack selection
This commit is contained in:
@@ -482,7 +482,7 @@ errout:
|
||||
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;
|
||||
@@ -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) {
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1029,6 +1034,26 @@ errout:
|
||||
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];
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -95,6 +96,7 @@ typedef enum {
|
||||
|
||||
struct dns_rule_flags {
|
||||
unsigned int flags;
|
||||
unsigned int is_flag_set;
|
||||
};
|
||||
|
||||
struct dns_address_IPV4 {
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user