conf: support prefix wildcard match.
This commit is contained in:
@@ -3372,6 +3372,8 @@ static int _dns_client_setup_server_packet(struct dns_server_info *server_info,
|
|||||||
struct dns_packet *packet = (struct dns_packet *)packet_buff;
|
struct dns_packet *packet = (struct dns_packet *)packet_buff;
|
||||||
struct dns_head head;
|
struct dns_head head;
|
||||||
int encode_len = 0;
|
int encode_len = 0;
|
||||||
|
int repack = 0;
|
||||||
|
int hitchhiking = 0;
|
||||||
|
|
||||||
*packet_data = default_packet;
|
*packet_data = default_packet;
|
||||||
*packet_data_len = default_packet_len;
|
*packet_data_len = default_packet_len;
|
||||||
@@ -3381,12 +3383,20 @@ static int _dns_client_setup_server_packet(struct dns_server_info *server_info,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server_info->ecs_ipv4.enable == false && query->qtype == DNS_T_A) {
|
if (server_info->ecs_ipv4.enable == true && query->qtype == DNS_T_A) {
|
||||||
/* no need to encode packet */
|
repack = 1;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server_info->ecs_ipv6.enable == false && query->qtype == DNS_T_AAAA) {
|
if (server_info->ecs_ipv6.enable == true && query->qtype == DNS_T_AAAA) {
|
||||||
|
repack = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((server_info->flags.server_flag & SERVER_FLAG_HITCHHIKING) != 0) {
|
||||||
|
hitchhiking = 1;
|
||||||
|
repack = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (repack == 0) {
|
||||||
/* no need to encode packet */
|
/* no need to encode packet */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3406,6 +3416,11 @@ static int _dns_client_setup_server_packet(struct dns_server_info *server_info,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hitchhiking != 0 && dns_add_domain(packet, "-", query->qtype, DNS_C_IN) != 0) {
|
||||||
|
tlog(TLOG_ERROR, "add domain to packet failed.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* add question */
|
/* add question */
|
||||||
if (dns_add_domain(packet, query->domain, query->qtype, DNS_C_IN) != 0) {
|
if (dns_add_domain(packet, query->domain, query->qtype, DNS_C_IN) != 0) {
|
||||||
tlog(TLOG_ERROR, "add domain to packet failed.");
|
tlog(TLOG_ERROR, "add domain to packet failed.");
|
||||||
|
|||||||
@@ -161,6 +161,8 @@ char dns_conf_user[DNS_CONF_USERNAME_LEN];
|
|||||||
int dns_save_fail_packet;
|
int dns_save_fail_packet;
|
||||||
char dns_save_fail_packet_dir[DNS_MAX_PATH];
|
char dns_save_fail_packet_dir[DNS_MAX_PATH];
|
||||||
char dns_resolv_file[DNS_MAX_PATH];
|
char dns_resolv_file[DNS_MAX_PATH];
|
||||||
|
int dns_no_pidfile;
|
||||||
|
int dns_no_daemon;
|
||||||
|
|
||||||
/* ECS */
|
/* ECS */
|
||||||
struct dns_edns_client_subnet dns_conf_ipv4_ecs;
|
struct dns_edns_client_subnet dns_conf_ipv4_ecs;
|
||||||
@@ -508,6 +510,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
|||||||
{"set-mark", required_argument, NULL, 254}, /* set mark */
|
{"set-mark", required_argument, NULL, 254}, /* set mark */
|
||||||
{"bootstrap-dns", no_argument, NULL, 255}, /* set as bootstrap dns */
|
{"bootstrap-dns", no_argument, NULL, 255}, /* set as bootstrap dns */
|
||||||
{"subnet", required_argument, NULL, 256}, /* set subnet */
|
{"subnet", required_argument, NULL, 256}, /* set subnet */
|
||||||
|
{"hitchhiking", no_argument, NULL, 257}, /* hitchhiking */
|
||||||
{NULL, no_argument, NULL, 0}
|
{NULL, no_argument, NULL, 0}
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
@@ -647,6 +650,9 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
|||||||
_conf_client_subnet(optarg, &server->ipv4_ecs, &server->ipv6_ecs);
|
_conf_client_subnet(optarg, &server->ipv4_ecs, &server->ipv6_ecs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 257: {
|
||||||
|
server_flag |= SERVER_FLAG_HITCHHIKING;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -841,6 +847,8 @@ static int _config_domain_rule_add(const char *domain, enum domain_rule type, vo
|
|||||||
|
|
||||||
char domain_key[DNS_MAX_CONF_CNAME_LEN];
|
char domain_key[DNS_MAX_CONF_CNAME_LEN];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
int sub_rule_only = 0;
|
||||||
|
int root_rule_only = 0;
|
||||||
|
|
||||||
/* Reverse string, for suffix match */
|
/* Reverse string, for suffix match */
|
||||||
len = strlen(domain);
|
len = strlen(domain);
|
||||||
@@ -849,6 +857,11 @@ static int _config_domain_rule_add(const char *domain, enum domain_rule type, vo
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len <= 0) {
|
||||||
|
tlog(TLOG_ERROR, "domain name %s too short", domain);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
if (strncmp(domain, "domain-set:", sizeof("domain-set:") - 1) == 0) {
|
if (strncmp(domain, "domain-set:", sizeof("domain-set:") - 1) == 0) {
|
||||||
struct dns_set_rule_add_callback_args args;
|
struct dns_set_rule_add_callback_args args;
|
||||||
args.type = type;
|
args.type = type;
|
||||||
@@ -858,8 +871,23 @@ static int _config_domain_rule_add(const char *domain, enum domain_rule type, vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
reverse_string(domain_key, domain, len, 1);
|
reverse_string(domain_key, domain, len, 1);
|
||||||
domain_key[len] = '.';
|
if (domain[0] == '*') {
|
||||||
len++;
|
/* prefix wildcard */
|
||||||
|
len--;
|
||||||
|
if (domain[1] == '.') {
|
||||||
|
sub_rule_only = 1;
|
||||||
|
}
|
||||||
|
} else if (domain[0] == '-') {
|
||||||
|
/* root match only */
|
||||||
|
len--;
|
||||||
|
if (domain[1] == '.') {
|
||||||
|
root_rule_only = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* suffix match */
|
||||||
|
domain_key[len] = '.';
|
||||||
|
len++;
|
||||||
|
}
|
||||||
domain_key[len] = 0;
|
domain_key[len] = 0;
|
||||||
|
|
||||||
if (type >= DOMAIN_RULE_MAX) {
|
if (type >= DOMAIN_RULE_MAX) {
|
||||||
@@ -884,6 +912,8 @@ static int _config_domain_rule_add(const char *domain, enum domain_rule type, vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
domain_rule->rules[type] = rule;
|
domain_rule->rules[type] = rule;
|
||||||
|
domain_rule->sub_rule_only = sub_rule_only;
|
||||||
|
domain_rule->root_rule_only = root_rule_only;
|
||||||
_dns_rule_get(rule);
|
_dns_rule_get(rule);
|
||||||
|
|
||||||
/* update domain rule */
|
/* update domain rule */
|
||||||
@@ -3517,6 +3547,8 @@ static struct config_item _config_item[] = {
|
|||||||
CONF_STRING("ca-path", (char *)&dns_conf_ca_path, DNS_MAX_PATH),
|
CONF_STRING("ca-path", (char *)&dns_conf_ca_path, DNS_MAX_PATH),
|
||||||
CONF_STRING("user", (char *)&dns_conf_user, sizeof(dns_conf_user)),
|
CONF_STRING("user", (char *)&dns_conf_user, sizeof(dns_conf_user)),
|
||||||
CONF_YESNO("debug-save-fail-packet", &dns_save_fail_packet),
|
CONF_YESNO("debug-save-fail-packet", &dns_save_fail_packet),
|
||||||
|
CONF_YESNO("no-pidfile", &dns_no_pidfile),
|
||||||
|
CONF_YESNO("no-daemon", &dns_no_daemon),
|
||||||
CONF_STRING("resolv-file", (char *)&dns_resolv_file, sizeof(dns_resolv_file)),
|
CONF_STRING("resolv-file", (char *)&dns_resolv_file, sizeof(dns_resolv_file)),
|
||||||
CONF_STRING("debug-save-fail-packet-dir", (char *)&dns_save_fail_packet_dir, sizeof(dns_save_fail_packet_dir)),
|
CONF_STRING("debug-save-fail-packet-dir", (char *)&dns_save_fail_packet_dir, sizeof(dns_save_fail_packet_dir)),
|
||||||
CONF_CUSTOM("conf-file", config_additional_file, NULL),
|
CONF_CUSTOM("conf-file", config_additional_file, NULL),
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ typedef enum {
|
|||||||
#define DOMAIN_FLAG_NO_CACHE (1 << 17)
|
#define DOMAIN_FLAG_NO_CACHE (1 << 17)
|
||||||
|
|
||||||
#define SERVER_FLAG_EXCLUDE_DEFAULT (1 << 0)
|
#define SERVER_FLAG_EXCLUDE_DEFAULT (1 << 0)
|
||||||
|
#define SERVER_FLAG_HITCHHIKING (1 << 1)
|
||||||
|
|
||||||
#define BIND_FLAG_NO_RULE_ADDR (1 << 0)
|
#define BIND_FLAG_NO_RULE_ADDR (1 << 0)
|
||||||
#define BIND_FLAG_NO_RULE_NAMESERVER (1 << 1)
|
#define BIND_FLAG_NO_RULE_NAMESERVER (1 << 1)
|
||||||
@@ -217,8 +218,9 @@ extern struct dns_nftset_names dns_conf_nftset_no_speed;
|
|||||||
|
|
||||||
struct dns_domain_rule {
|
struct dns_domain_rule {
|
||||||
struct dns_rule head;
|
struct dns_rule head;
|
||||||
|
unsigned char sub_rule_only : 1;
|
||||||
|
unsigned char root_rule_only : 1;
|
||||||
struct dns_rule *rules[DOMAIN_RULE_MAX];
|
struct dns_rule *rules[DOMAIN_RULE_MAX];
|
||||||
int is_sub_rule[DOMAIN_RULE_MAX];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dns_nameserver_rule {
|
struct dns_nameserver_rule {
|
||||||
@@ -517,6 +519,9 @@ extern int dns_save_fail_packet;
|
|||||||
extern char dns_save_fail_packet_dir[DNS_MAX_PATH];
|
extern char dns_save_fail_packet_dir[DNS_MAX_PATH];
|
||||||
extern char dns_resolv_file[DNS_MAX_PATH];
|
extern char dns_resolv_file[DNS_MAX_PATH];
|
||||||
|
|
||||||
|
extern int dns_no_pidfile;
|
||||||
|
extern int dns_no_daemon;
|
||||||
|
|
||||||
void dns_server_load_exit(void);
|
void dns_server_load_exit(void);
|
||||||
|
|
||||||
int dns_server_load_conf(const char *file);
|
int dns_server_load_conf(const char *file);
|
||||||
|
|||||||
@@ -216,6 +216,11 @@ struct dns_request_pending_list {
|
|||||||
struct hlist_node node;
|
struct hlist_node node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dns_request_domain_rule {
|
||||||
|
struct dns_rule *rules[DOMAIN_RULE_MAX];
|
||||||
|
int is_sub_rule[DOMAIN_RULE_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
typedef DNS_CHILD_POST_RESULT (*child_request_callback)(struct dns_request *request, struct dns_request *child_request,
|
typedef DNS_CHILD_POST_RESULT (*child_request_callback)(struct dns_request *request, struct dns_request *child_request,
|
||||||
int is_first_resp);
|
int is_first_resp);
|
||||||
|
|
||||||
@@ -303,7 +308,7 @@ struct dns_request {
|
|||||||
atomic_t ip_map_num;
|
atomic_t ip_map_num;
|
||||||
DECLARE_HASHTABLE(ip_map, 4);
|
DECLARE_HASHTABLE(ip_map, 4);
|
||||||
|
|
||||||
struct dns_domain_rule domain_rule;
|
struct dns_request_domain_rule domain_rule;
|
||||||
int skip_domain_rule;
|
int skip_domain_rule;
|
||||||
struct dns_domain_check_orders *check_order_list;
|
struct dns_domain_check_orders *check_order_list;
|
||||||
int check_order;
|
int check_order;
|
||||||
@@ -710,7 +715,7 @@ static void _dns_server_audit_log(struct dns_server_post_context *context)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 1; j < DNS_RRS_END && context->packet; j++) {
|
for (j = 1; j < DNS_RRS_OPT && context->packet; j++) {
|
||||||
rrs = dns_get_rrs_start(context->packet, j, &rr_count);
|
rrs = dns_get_rrs_start(context->packet, j, &rr_count);
|
||||||
for (i = 0; i < rr_count && rrs && left_len > 0; i++, rrs = dns_get_rrs_next(context->packet, rrs)) {
|
for (i = 0; i < rr_count && rrs && left_len > 0; i++, rrs = dns_get_rrs_next(context->packet, rrs)) {
|
||||||
switch (rrs->type) {
|
switch (rrs->type) {
|
||||||
@@ -1341,7 +1346,7 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 1; j < DNS_RRS_END && context->packet; j++) {
|
for (j = 1; j < DNS_RRS_OPT && context->packet; j++) {
|
||||||
rrs = dns_get_rrs_start(context->packet, j, &rr_count);
|
rrs = dns_get_rrs_start(context->packet, j, &rr_count);
|
||||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(context->packet, rrs)) {
|
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(context->packet, rrs)) {
|
||||||
switch (rrs->type) {
|
switch (rrs->type) {
|
||||||
@@ -1699,7 +1704,7 @@ static int _dns_server_setup_ipset_nftset_packet(struct dns_server_post_context
|
|||||||
timeout_value = _dns_server_get_conf_ttl(request, 0) * 3;
|
timeout_value = _dns_server_get_conf_ttl(request, 0) * 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 1; j < DNS_RRS_END; j++) {
|
for (j = 1; j < DNS_RRS_OPT; j++) {
|
||||||
rrs = dns_get_rrs_start(context->packet, j, &rr_count);
|
rrs = dns_get_rrs_start(context->packet, j, &rr_count);
|
||||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(context->packet, rrs)) {
|
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(context->packet, rrs)) {
|
||||||
switch (rrs->type) {
|
switch (rrs->type) {
|
||||||
@@ -2993,7 +2998,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
|
|||||||
request->rcode = packet->head.rcode;
|
request->rcode = packet->head.rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 1; j < DNS_RRS_END; j++) {
|
for (j = 1; j < DNS_RRS_OPT; j++) {
|
||||||
rrs = dns_get_rrs_start(packet, j, &rr_count);
|
rrs = dns_get_rrs_start(packet, j, &rr_count);
|
||||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
||||||
switch (rrs->type) {
|
switch (rrs->type) {
|
||||||
@@ -3057,7 +3062,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
tlog(TLOG_DEBUG, "%s, qtype: %d", name, rrs->type);
|
tlog(TLOG_DEBUG, "%s, qtype: %d, rrstype = %d", name, rrs->type, j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3093,7 +3098,7 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, const
|
|||||||
request->rcode = packet->head.rcode;
|
request->rcode = packet->head.rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 1; j < DNS_RRS_END; j++) {
|
for (j = 1; j < DNS_RRS_OPT; j++) {
|
||||||
rrs = dns_get_rrs_start(packet, j, &rr_count);
|
rrs = dns_get_rrs_start(packet, j, &rr_count);
|
||||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
||||||
switch (rrs->type) {
|
switch (rrs->type) {
|
||||||
@@ -3219,7 +3224,7 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
|
|||||||
struct dns_request *request = context->request;
|
struct dns_request *request = context->request;
|
||||||
struct dns_packet *packet = context->packet;
|
struct dns_packet *packet = context->packet;
|
||||||
|
|
||||||
for (j = 1; j < DNS_RRS_END; j++) {
|
for (j = 1; j < DNS_RRS_OPT; j++) {
|
||||||
rrs = dns_get_rrs_start(packet, j, &rr_count);
|
rrs = dns_get_rrs_start(packet, j, &rr_count);
|
||||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
||||||
switch (rrs->type) {
|
switch (rrs->type) {
|
||||||
@@ -3925,6 +3930,16 @@ static int _dns_server_get_rules(unsigned char *key, uint32_t key_len, int is_su
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* only subkey rule */
|
||||||
|
if (domain_rule->sub_rule_only == 1 && is_subkey == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* only root key rule */
|
||||||
|
if (domain_rule->root_rule_only == 1 && is_subkey == 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < DOMAIN_RULE_MAX; i++) {
|
for (i = 0; i < DOMAIN_RULE_MAX; i++) {
|
||||||
if (domain_rule->rules[i] == NULL) {
|
if (domain_rule->rules[i] == NULL) {
|
||||||
continue;
|
continue;
|
||||||
@@ -4331,7 +4346,7 @@ static int _dns_server_process_cname_pre(struct dns_request *request)
|
|||||||
{
|
{
|
||||||
struct dns_cname_rule *cname = NULL;
|
struct dns_cname_rule *cname = NULL;
|
||||||
struct dns_rule_flags *rule_flag = NULL;
|
struct dns_rule_flags *rule_flag = NULL;
|
||||||
struct dns_domain_rule domain_rule;
|
struct dns_request_domain_rule domain_rule;
|
||||||
|
|
||||||
if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_RULE_CNAME) == 0) {
|
if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_RULE_CNAME) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -810,7 +810,7 @@ int main(int argc, char *argv[])
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_foreground == 0) {
|
if (is_foreground == 0 && dns_no_daemon == 0) {
|
||||||
daemon_ret = run_daemon();
|
daemon_ret = run_daemon();
|
||||||
if (daemon_ret < 0) {
|
if (daemon_ret < 0) {
|
||||||
char buff[4096];
|
char buff[4096];
|
||||||
@@ -831,7 +831,7 @@ int main(int argc, char *argv[])
|
|||||||
_reg_signal();
|
_reg_signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(pid_file, "-", 2) != 0 && create_pid_file(pid_file) != 0) {
|
if (strncmp(pid_file, "-", 2) != 0 && dns_no_pidfile == 0 && create_pid_file(pid_file) != 0) {
|
||||||
ret = -2;
|
ret = -2;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|||||||
262
test/cases/test-rule.cc
Normal file
262
test/cases/test-rule.cc
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
/*************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||||
|
*
|
||||||
|
* smartdns is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* smartdns is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* 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 "client.h"
|
||||||
|
#include "dns.h"
|
||||||
|
#include "include/utils.h"
|
||||||
|
#include "server.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
class Rule : public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
virtual void SetUp() {}
|
||||||
|
virtual void TearDown() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(Rule, Match)
|
||||||
|
{
|
||||||
|
smartdns::MockServer server_upstream;
|
||||||
|
smartdns::Server server;
|
||||||
|
|
||||||
|
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||||
|
if (request->qtype == DNS_T_A) {
|
||||||
|
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 700);
|
||||||
|
return smartdns::SERVER_REQUEST_OK;
|
||||||
|
} else if (request->qtype == DNS_T_AAAA) {
|
||||||
|
smartdns::MockServer::AddIP(request, request->domain.c_str(), "64:ff9b::102:304", 700);
|
||||||
|
return smartdns::SERVER_REQUEST_OK;
|
||||||
|
}
|
||||||
|
return smartdns::SERVER_REQUEST_SOA;
|
||||||
|
});
|
||||||
|
|
||||||
|
server.Start(R"""(bind [::]:60053
|
||||||
|
server 127.0.0.1:61053
|
||||||
|
log-num 0
|
||||||
|
log-console yes
|
||||||
|
log-level debug
|
||||||
|
speed-check-mode none
|
||||||
|
address /a.com/5.6.7.8
|
||||||
|
cache-persist no)""");
|
||||||
|
smartdns::Client client;
|
||||||
|
ASSERT_TRUE(client.Query("a.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "5.6.7.8");
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.Query("a.a.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.a.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "5.6.7.8");
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.Query("aa.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "aa.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Rule, PrefixWildcardMatch)
|
||||||
|
{
|
||||||
|
smartdns::MockServer server_upstream;
|
||||||
|
smartdns::Server server;
|
||||||
|
|
||||||
|
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||||
|
if (request->qtype == DNS_T_A) {
|
||||||
|
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 700);
|
||||||
|
return smartdns::SERVER_REQUEST_OK;
|
||||||
|
} else if (request->qtype == DNS_T_AAAA) {
|
||||||
|
smartdns::MockServer::AddIP(request, request->domain.c_str(), "64:ff9b::102:304", 700);
|
||||||
|
return smartdns::SERVER_REQUEST_OK;
|
||||||
|
}
|
||||||
|
return smartdns::SERVER_REQUEST_SOA;
|
||||||
|
});
|
||||||
|
|
||||||
|
server.Start(R"""(bind [::]:60053
|
||||||
|
server 127.0.0.1:61053
|
||||||
|
log-num 0
|
||||||
|
log-console yes
|
||||||
|
log-level debug
|
||||||
|
speed-check-mode none
|
||||||
|
address /*a.com/5.6.7.8
|
||||||
|
cache-persist no)""");
|
||||||
|
smartdns::Client client;
|
||||||
|
ASSERT_TRUE(client.Query("a.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "5.6.7.8");
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.Query("a.a.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.a.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "5.6.7.8");
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.Query("aa.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "aa.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "5.6.7.8");
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.Query("ab.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "ab.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Rule, SubDomainMatchOnly)
|
||||||
|
{
|
||||||
|
smartdns::MockServer server_upstream;
|
||||||
|
smartdns::Server server;
|
||||||
|
|
||||||
|
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||||
|
if (request->qtype == DNS_T_A) {
|
||||||
|
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 700);
|
||||||
|
return smartdns::SERVER_REQUEST_OK;
|
||||||
|
} else if (request->qtype == DNS_T_AAAA) {
|
||||||
|
smartdns::MockServer::AddIP(request, request->domain.c_str(), "64:ff9b::102:304", 700);
|
||||||
|
return smartdns::SERVER_REQUEST_OK;
|
||||||
|
}
|
||||||
|
return smartdns::SERVER_REQUEST_SOA;
|
||||||
|
});
|
||||||
|
|
||||||
|
server.Start(R"""(bind [::]:60053
|
||||||
|
server 127.0.0.1:61053
|
||||||
|
log-num 0
|
||||||
|
log-console yes
|
||||||
|
log-level debug
|
||||||
|
speed-check-mode none
|
||||||
|
address /*.a.com/5.6.7.8
|
||||||
|
cache-persist no)""");
|
||||||
|
smartdns::Client client;
|
||||||
|
ASSERT_TRUE(client.Query("a.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.Query("a.a.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.a.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "5.6.7.8");
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.Query("aa.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "aa.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Rule, RootDomainMatchOnly)
|
||||||
|
{
|
||||||
|
smartdns::MockServer server_upstream;
|
||||||
|
smartdns::Server server;
|
||||||
|
|
||||||
|
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||||
|
if (request->qtype == DNS_T_A) {
|
||||||
|
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 700);
|
||||||
|
return smartdns::SERVER_REQUEST_OK;
|
||||||
|
} else if (request->qtype == DNS_T_AAAA) {
|
||||||
|
smartdns::MockServer::AddIP(request, request->domain.c_str(), "64:ff9b::102:304", 700);
|
||||||
|
return smartdns::SERVER_REQUEST_OK;
|
||||||
|
}
|
||||||
|
return smartdns::SERVER_REQUEST_SOA;
|
||||||
|
});
|
||||||
|
|
||||||
|
server.Start(R"""(bind [::]:60053
|
||||||
|
server 127.0.0.1:61053
|
||||||
|
log-num 0
|
||||||
|
log-console yes
|
||||||
|
log-level debug
|
||||||
|
speed-check-mode none
|
||||||
|
address /-.a.com/5.6.7.8
|
||||||
|
cache-persist no)""");
|
||||||
|
smartdns::Client client;
|
||||||
|
ASSERT_TRUE(client.Query("a.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "5.6.7.8");
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.Query("a.a.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.a.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.Query("b.a.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "b.a.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||||
|
|
||||||
|
ASSERT_TRUE(client.Query("ba.com A", 60053));
|
||||||
|
std::cout << client.GetResult() << std::endl;
|
||||||
|
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||||
|
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetName(), "ba.com");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||||
|
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user