config: add option -no-cache and -response-mode for domain-rules and add some test cases.
This commit is contained in:
@@ -202,6 +202,9 @@ static void *_new_dns_rule(enum domain_rule domain_rule)
|
||||
case DOMAIN_RULE_CHECKSPEED:
|
||||
size = sizeof(struct dns_domain_check_orders);
|
||||
break;
|
||||
case DOMAIN_RULE_RESPONSE_MODE:
|
||||
size = sizeof(struct dns_response_mode_rule);
|
||||
break;
|
||||
case DOMAIN_RULE_CNAME:
|
||||
size = sizeof(struct dns_cname_rule);
|
||||
break;
|
||||
@@ -2388,6 +2391,38 @@ errout:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _conf_domain_rule_response_mode(char *domain, const char *mode)
|
||||
{
|
||||
enum response_mode_type response_mode_type = DNS_RESPONSE_MODE_FIRST_PING_IP;
|
||||
struct dns_response_mode_rule *response_mode = NULL;
|
||||
|
||||
for (int i = 0; dns_conf_response_mode_enum[i].name != NULL; i++) {
|
||||
if (strcmp(mode, dns_conf_response_mode_enum[i].name) == 0) {
|
||||
response_mode_type = dns_conf_response_mode_enum[i].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
response_mode = _new_dns_rule(DOMAIN_RULE_RESPONSE_MODE);
|
||||
if (response_mode == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
response_mode->mode = response_mode_type;
|
||||
|
||||
if (_config_domain_rule_add(domain, DOMAIN_RULE_RESPONSE_MODE, response_mode) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
_dns_rule_put(&response_mode->head);
|
||||
return 0;
|
||||
errout:
|
||||
if (response_mode) {
|
||||
_dns_rule_put(&response_mode->head);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _conf_domain_set(void *data, int argc, char *argv[])
|
||||
{
|
||||
int opt = 0;
|
||||
@@ -2527,6 +2562,11 @@ static int _conf_domain_rule_delete(const char *domain)
|
||||
return _config_domain_rule_delete(domain);
|
||||
}
|
||||
|
||||
static int _conf_domain_rule_no_cache(const char *domain)
|
||||
{
|
||||
return _config_domain_rule_flag_set(domain, DOMAIN_FLAG_NO_CACHE, 0);
|
||||
}
|
||||
|
||||
static int _conf_domain_rules(void *data, int argc, char *argv[])
|
||||
{
|
||||
int opt = 0;
|
||||
@@ -2539,6 +2579,7 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
|
||||
/* clang-format off */
|
||||
static struct option long_options[] = {
|
||||
{"speed-check-mode", required_argument, NULL, 'c'},
|
||||
{"response-mode", required_argument, NULL, 'r'},
|
||||
{"address", required_argument, NULL, 'a'},
|
||||
{"ipset", required_argument, NULL, 'p'},
|
||||
{"nftset", required_argument, NULL, 't'},
|
||||
@@ -2550,6 +2591,7 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
|
||||
{"rr-ttl-max", required_argument, NULL, 253},
|
||||
{"no-serve-expired", no_argument, NULL, 254},
|
||||
{"delete", no_argument, NULL, 255},
|
||||
{"no-cache", no_argument, NULL, 256},
|
||||
{NULL, no_argument, NULL, 0}
|
||||
};
|
||||
/* clang-format on */
|
||||
@@ -2566,7 +2608,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, "c:a:p:t:n:d:A:", long_options, NULL);
|
||||
opt = getopt_long_only(argc, argv, "c:a:p:t:n:d:A:r:", long_options, NULL);
|
||||
if (opt == -1) {
|
||||
break;
|
||||
}
|
||||
@@ -2585,6 +2627,19 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
|
||||
|
||||
break;
|
||||
}
|
||||
case 'r': {
|
||||
const char *response_mode = optarg;
|
||||
if (response_mode == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (_conf_domain_rule_response_mode(domain, response_mode) != 0) {
|
||||
tlog(TLOG_ERROR, "add response-mode rule failed.");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 'a': {
|
||||
const char *address = optarg;
|
||||
if (address == NULL) {
|
||||
@@ -2684,6 +2739,14 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
|
||||
|
||||
return 0;
|
||||
}
|
||||
case 256: {
|
||||
if (_conf_domain_rule_no_cache(domain) != 0) {
|
||||
tlog(TLOG_ERROR, "set no-cache rule failed.");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ enum domain_rule {
|
||||
DOMAIN_RULE_NFTSET_IP6,
|
||||
DOMAIN_RULE_NAMESERVER,
|
||||
DOMAIN_RULE_CHECKSPEED,
|
||||
DOMAIN_RULE_RESPONSE_MODE,
|
||||
DOMAIN_RULE_CNAME,
|
||||
DOMAIN_RULE_TTL,
|
||||
DOMAIN_RULE_MAX,
|
||||
@@ -110,6 +111,7 @@ typedef enum {
|
||||
#define DOMAIN_FLAG_NFTSET_IP6_IGN (1 << 14)
|
||||
#define DOMAIN_FLAG_NO_SERVE_EXPIRED (1 << 15)
|
||||
#define DOMAIN_FLAG_CNAME_IGN (1 << 16)
|
||||
#define DOMAIN_FLAG_NO_CACHE (1 << 17)
|
||||
|
||||
#define SERVER_FLAG_EXCLUDE_DEFAULT (1 << 0)
|
||||
|
||||
@@ -124,6 +126,12 @@ typedef enum {
|
||||
#define BIND_FLAG_FORCE_AAAA_SOA (1 << 8)
|
||||
#define BIND_FLAG_NO_RULE_CNAME (1 << 9)
|
||||
|
||||
enum response_mode_type {
|
||||
DNS_RESPONSE_MODE_FIRST_PING_IP = 0,
|
||||
DNS_RESPONSE_MODE_FASTEST_IP,
|
||||
DNS_RESPONSE_MODE_FASTEST_RESPONSE,
|
||||
};
|
||||
|
||||
struct dns_rule {
|
||||
atomic_t refcnt;
|
||||
enum domain_rule rule;
|
||||
@@ -227,6 +235,11 @@ struct dns_domain_check_orders {
|
||||
struct dns_domain_check_order orders[DOMAIN_CHECK_NUM];
|
||||
};
|
||||
|
||||
struct dns_response_mode_rule {
|
||||
struct dns_rule head;
|
||||
enum response_mode_type mode;
|
||||
};
|
||||
|
||||
struct dns_group_table {
|
||||
DECLARE_HASHTABLE(group, 8);
|
||||
};
|
||||
@@ -464,11 +477,6 @@ extern int dns_conf_dualstack_ip_allow_force_AAAA;
|
||||
extern int dns_conf_dualstack_ip_selection_threshold;
|
||||
|
||||
extern int dns_conf_max_reply_ip_num;
|
||||
enum response_mode_type {
|
||||
DNS_RESPONSE_MODE_FIRST_PING_IP = 0,
|
||||
DNS_RESPONSE_MODE_FASTEST_IP,
|
||||
DNS_RESPONSE_MODE_FASTEST_RESPONSE,
|
||||
};
|
||||
extern enum response_mode_type dns_conf_response_mode;
|
||||
|
||||
extern int dns_conf_rr_ttl;
|
||||
|
||||
@@ -304,10 +304,13 @@ struct dns_request {
|
||||
struct dns_domain_check_orders *check_order_list;
|
||||
int check_order;
|
||||
|
||||
enum response_mode_type response_mode;
|
||||
|
||||
struct dns_request_pending_list *request_pending_list;
|
||||
|
||||
int no_select_possible_ip;
|
||||
int no_cache_cname;
|
||||
int no_cache;
|
||||
};
|
||||
|
||||
/* dns server data */
|
||||
@@ -1269,7 +1272,7 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
|
||||
|
||||
struct dns_request *request = context->request;
|
||||
|
||||
if (request->has_cname == 0 || request->no_cache_cname == 1) {
|
||||
if (request->has_cname == 0 || request->no_cache_cname == 1 || request->no_cache == 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1514,7 +1517,7 @@ static int _dns_cache_reply_packet(struct dns_server_post_context *context)
|
||||
{
|
||||
struct dns_request *request = context->request;
|
||||
int has_soa = request->has_soa;
|
||||
if (context->do_cache == 0 || _dns_server_has_bind_flag(request, BIND_FLAG_NO_CACHE) == 0) {
|
||||
if (context->do_cache == 0 || request->no_cache == 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2433,6 +2436,7 @@ static struct dns_request *_dns_server_new_request(void)
|
||||
request->qclass = DNS_C_IN;
|
||||
request->result_callback = NULL;
|
||||
request->check_order_list = &dns_conf_check_orders;
|
||||
request->response_mode = dns_conf_response_mode;
|
||||
INIT_LIST_HEAD(&request->list);
|
||||
INIT_LIST_HEAD(&request->pending_list);
|
||||
INIT_LIST_HEAD(&request->check_list);
|
||||
@@ -2585,7 +2589,7 @@ out:
|
||||
}
|
||||
|
||||
/* Get first ping result */
|
||||
if (dns_conf_response_mode == DNS_RESPONSE_MODE_FIRST_PING_IP && last_rtt == -1 && request->ping_time > 0) {
|
||||
if (request->response_mode == DNS_RESPONSE_MODE_FIRST_PING_IP && last_rtt == -1 && request->ping_time > 0) {
|
||||
may_complete = 1;
|
||||
}
|
||||
|
||||
@@ -3422,7 +3426,7 @@ static int dns_server_resolve_callback(const char *domain, dns_result_type rtype
|
||||
return _dns_server_reply_passthrough(&context);
|
||||
}
|
||||
|
||||
if (request->prefetch == 0 && dns_conf_response_mode == DNS_RESPONSE_MODE_FASTEST_RESPONSE &&
|
||||
if (request->prefetch == 0 && request->response_mode == DNS_RESPONSE_MODE_FASTEST_RESPONSE &&
|
||||
atomic_read(&request->notified) == 0) {
|
||||
struct dns_server_post_context context;
|
||||
int ttl = 0;
|
||||
@@ -3936,6 +3940,10 @@ static int _dns_server_pre_process_rule_flags(struct dns_request *request)
|
||||
request->no_serve_expired = 1;
|
||||
}
|
||||
|
||||
if ((flags & DOMAIN_FLAG_NO_CACHE) || (_dns_server_has_bind_flag(request, BIND_FLAG_NO_CACHE) == 0)) {
|
||||
request->no_cache = 1;
|
||||
}
|
||||
|
||||
if (flags & DOMAIN_FLAG_ADDR_IGN) {
|
||||
/* ignore this domain */
|
||||
goto out;
|
||||
@@ -4432,17 +4440,22 @@ static int _dns_server_qtype_soa(struct dns_request *request)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void _dns_server_process_speed_check_rule(struct dns_request *request)
|
||||
static void _dns_server_process_speed_rule(struct dns_request *request)
|
||||
{
|
||||
struct dns_domain_check_orders *check_order = NULL;
|
||||
struct dns_response_mode_rule *response_mode = NULL;
|
||||
|
||||
/* get domain rule flag */
|
||||
/* get speed check mode */
|
||||
check_order = _dns_server_get_dns_rule(request, DOMAIN_RULE_CHECKSPEED);
|
||||
if (check_order == NULL) {
|
||||
return;
|
||||
if (check_order != NULL) {
|
||||
request->check_order_list = check_order;
|
||||
}
|
||||
|
||||
request->check_order_list = check_order;
|
||||
/* get response mode */
|
||||
response_mode = _dns_server_get_dns_rule(request, DOMAIN_RULE_RESPONSE_MODE);
|
||||
if (response_mode != NULL) {
|
||||
request->response_mode = response_mode->mode;
|
||||
}
|
||||
}
|
||||
|
||||
static int _dns_server_get_expired_ttl_reply(struct dns_cache *dns_cache)
|
||||
@@ -5073,7 +5086,7 @@ static int _dns_server_do_query(struct dns_request *request, int skip_notify_eve
|
||||
}
|
||||
|
||||
/* process speed check rule */
|
||||
_dns_server_process_speed_check_rule(request);
|
||||
_dns_server_process_speed_rule(request);
|
||||
|
||||
/* check and set passthrough */
|
||||
_dns_server_check_set_passthrough(request);
|
||||
|
||||
Reference in New Issue
Block a user