Skip to content

Commit

Permalink
conf: support prefix wildcard match.
Browse files Browse the repository at this point in the history
  • Loading branch information
pymumu committed Jul 4, 2023
1 parent 087c9f5 commit 6b02194
Show file tree
Hide file tree
Showing 6 changed files with 347 additions and 18 deletions.
23 changes: 19 additions & 4 deletions src/dns_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_head head;
int encode_len = 0;
int repack = 0;
int hitchhiking = 0;

*packet_data = default_packet;
*packet_data_len = default_packet_len;
Expand All @@ -3381,12 +3383,20 @@ static int _dns_client_setup_server_packet(struct dns_server_info *server_info,
return 0;
}

if (server_info->ecs_ipv4.enable == false && query->qtype == DNS_T_A) {
/* no need to encode packet */
return 0;
if (server_info->ecs_ipv4.enable == true && query->qtype == DNS_T_A) {
repack = 1;
}

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 (server_info->ecs_ipv6.enable == false && query->qtype == DNS_T_AAAA) {
if (repack == 0) {
/* no need to encode packet */
return 0;
}
Expand All @@ -3406,6 +3416,11 @@ static int _dns_client_setup_server_packet(struct dns_server_info *server_info,
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 */
if (dns_add_domain(packet, query->domain, query->qtype, DNS_C_IN) != 0) {
tlog(TLOG_ERROR, "add domain to packet failed.");
Expand Down
36 changes: 34 additions & 2 deletions src/dns_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ char dns_conf_user[DNS_CONF_USERNAME_LEN];
int dns_save_fail_packet;
char dns_save_fail_packet_dir[DNS_MAX_PATH];
char dns_resolv_file[DNS_MAX_PATH];
int dns_no_pidfile;
int dns_no_daemon;

/* ECS */
struct dns_edns_client_subnet dns_conf_ipv4_ecs;
Expand Down Expand Up @@ -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 */
{"bootstrap-dns", no_argument, NULL, 255}, /* set as bootstrap dns */
{"subnet", required_argument, NULL, 256}, /* set subnet */
{"hitchhiking", no_argument, NULL, 257}, /* hitchhiking */
{NULL, no_argument, NULL, 0}
};
/* clang-format on */
Expand Down Expand Up @@ -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);
break;
}
case 257: {
server_flag |= SERVER_FLAG_HITCHHIKING;
}
default:
break;
}
Expand Down Expand Up @@ -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];
int len = 0;
int sub_rule_only = 0;
int root_rule_only = 0;

/* Reverse string, for suffix match */
len = strlen(domain);
Expand All @@ -849,6 +857,11 @@ static int _config_domain_rule_add(const char *domain, enum domain_rule type, vo
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) {
struct dns_set_rule_add_callback_args args;
args.type = type;
Expand All @@ -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);
domain_key[len] = '.';
len++;
if (domain[0] == '*') {
/* 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;

if (type >= DOMAIN_RULE_MAX) {
Expand All @@ -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->sub_rule_only = sub_rule_only;
domain_rule->root_rule_only = root_rule_only;
_dns_rule_get(rule);

/* update domain rule */
Expand Down Expand Up @@ -3517,6 +3547,8 @@ static struct config_item _config_item[] = {
CONF_STRING("ca-path", (char *)&dns_conf_ca_path, DNS_MAX_PATH),
CONF_STRING("user", (char *)&dns_conf_user, sizeof(dns_conf_user)),
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("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),
Expand Down
7 changes: 6 additions & 1 deletion src/dns_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ typedef enum {
#define DOMAIN_FLAG_NO_CACHE (1 << 17)

#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_NAMESERVER (1 << 1)
Expand Down Expand Up @@ -217,8 +218,9 @@ extern struct dns_nftset_names dns_conf_nftset_no_speed;

struct dns_domain_rule {
struct dns_rule head;
unsigned char sub_rule_only : 1;
unsigned char root_rule_only : 1;
struct dns_rule *rules[DOMAIN_RULE_MAX];
int is_sub_rule[DOMAIN_RULE_MAX];
};

struct dns_nameserver_rule {
Expand Down Expand Up @@ -517,6 +519,9 @@ extern int dns_save_fail_packet;
extern char dns_save_fail_packet_dir[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);

int dns_server_load_conf(const char *file);
Expand Down
33 changes: 24 additions & 9 deletions src/dns_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ struct dns_request_pending_list {
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,
int is_first_resp);

Expand Down Expand Up @@ -303,7 +308,7 @@ struct dns_request {
atomic_t ip_map_num;
DECLARE_HASHTABLE(ip_map, 4);

struct dns_domain_rule domain_rule;
struct dns_request_domain_rule domain_rule;
int skip_domain_rule;
struct dns_domain_check_orders *check_order_list;
int check_order;
Expand Down Expand Up @@ -710,7 +715,7 @@ static void _dns_server_audit_log(struct dns_server_post_context *context)
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);
for (i = 0; i < rr_count && rrs && left_len > 0; i++, rrs = dns_get_rrs_next(context->packet, rrs)) {
switch (rrs->type) {
Expand Down Expand Up @@ -1341,7 +1346,7 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
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);
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(context->packet, rrs)) {
switch (rrs->type) {
Expand Down Expand Up @@ -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;
}

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);
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(context->packet, rrs)) {
switch (rrs->type) {
Expand Down Expand Up @@ -2993,7 +2998,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
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);
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
switch (rrs->type) {
Expand Down Expand Up @@ -3057,7 +3062,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
}
} break;
default:
tlog(TLOG_DEBUG, "%s, qtype: %d", name, rrs->type);
tlog(TLOG_DEBUG, "%s, qtype: %d, rrstype = %d", name, rrs->type, j);
break;
}
}
Expand Down Expand Up @@ -3093,7 +3098,7 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, const
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);
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
switch (rrs->type) {
Expand Down Expand Up @@ -3219,7 +3224,7 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
struct dns_request *request = context->request;
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);
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
switch (rrs->type) {
Expand Down Expand Up @@ -3925,6 +3930,16 @@ static int _dns_server_get_rules(unsigned char *key, uint32_t key_len, int is_su
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++) {
if (domain_rule->rules[i] == NULL) {
continue;
Expand Down Expand Up @@ -4331,7 +4346,7 @@ static int _dns_server_process_cname_pre(struct dns_request *request)
{
struct dns_cname_rule *cname = 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) {
return 0;
Expand Down
4 changes: 2 additions & 2 deletions src/smartdns.c
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ int main(int argc, char *argv[])
goto errout;
}

if (is_foreground == 0) {
if (is_foreground == 0 && dns_no_daemon == 0) {
daemon_ret = run_daemon();
if (daemon_ret < 0) {
char buff[4096];
Expand All @@ -831,7 +831,7 @@ int main(int argc, char *argv[])
_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;
goto errout;
}
Expand Down
Loading

0 comments on commit 6b02194

Please sign in to comment.