Skip to content

Commit 1ef9da8

Browse files
committed
dns-server: fix cname rule issue
1 parent 66b86e1 commit 1ef9da8

File tree

4 files changed

+75
-41
lines changed

4 files changed

+75
-41
lines changed

src/dns.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,13 +1687,13 @@ static int _dns_decode_opt_cookie(struct dns_context *context, struct dns_opt_co
16871687
return 0;
16881688
}
16891689

1690-
if (opt_len < (int)member_size(struct dns_opt_cookie, server_cookie)) {
1690+
if (opt_len < 8 || opt_len > (int)member_size(struct dns_opt_cookie, server_cookie)) {
16911691
return -1;
16921692
}
16931693

1694-
memcpy(cookie->server_cookie, context->ptr, len);
1695-
cookie->server_cookie_len = len;
1696-
context->ptr += len;
1694+
memcpy(cookie->server_cookie, context->ptr, opt_len);
1695+
cookie->server_cookie_len = opt_len;
1696+
context->ptr += opt_len;
16971697

16981698
tlog(TLOG_DEBUG, "OPT COOKIE");
16991699
return 0;
@@ -1860,8 +1860,8 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
18601860
}
18611861

18621862
if (errcode != 0) {
1863-
tlog(TLOG_ERROR, "extend rcode invalid.");
1864-
return -1;
1863+
tlog(TLOG_DEBUG, "extend rcode invalid, %d", errcode);
1864+
return 0;
18651865
}
18661866

18671867
while (context->ptr - start < rr_len) {

src/dns.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ struct dns_opt_ecs {
198198
unsigned char addr[DNS_RR_AAAA_LEN];
199199
} __attribute__((packed));
200200

201-
/* OPT COOLIE */
201+
/* OPT COOKIE */
202202
struct dns_opt_cookie {
203203
char server_cookie_len;
204204
unsigned char client_cookie[8];

src/dns_conf.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,12 @@ typedef enum {
8585
DNS_BIND_TYPE_TLS,
8686
} DNS_BIND_TYPE;
8787

88-
#define DOMAIN_CHECK_NONE 0
89-
#define DOMAIN_CHECK_ICMP 1
90-
#define DOMAIN_CHECK_TCP 2
91-
#define DOMAIN_CHECK_NUM 3
88+
typedef enum {
89+
DOMAIN_CHECK_NONE = 0,
90+
DOMAIN_CHECK_ICMP = 1,
91+
DOMAIN_CHECK_TCP = 2,
92+
DOMAIN_CHECK_NUM = 3,
93+
} DOMAIN_CHECK_TYPE;
9294

9395
#define DOMAIN_FLAG_ADDR_SOA (1 << 0)
9496
#define DOMAIN_FLAG_ADDR_IPV4_SOA (1 << 1)
@@ -215,7 +217,7 @@ struct dns_server_groups {
215217
};
216218

217219
struct dns_domain_check_order {
218-
char type;
220+
DOMAIN_CHECK_TYPE type;
219221
unsigned short tcp_port;
220222
};
221223

src/dns_server.c

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@ static int _dns_server_request_update_cache(struct dns_request *request, dns_typ
11311131
} else {
11321132
ttl = dns_conf_rr_ttl;
11331133
if (ttl == 0) {
1134-
ttl = DNS_SERVER_TMOUT_TTL;
1134+
ttl = _dns_server_get_conf_ttl(request, request->ip_ttl);
11351135
}
11361136
}
11371137

@@ -1837,7 +1837,7 @@ static void _dns_server_check_complete_dualstack(struct dns_request *request, st
18371837
return;
18381838
}
18391839

1840-
if (request->ping_time <= (dns_conf_dualstack_ip_selection_threshold * 10) ) {
1840+
if (request->ping_time <= (dns_conf_dualstack_ip_selection_threshold * 10)) {
18411841
return;
18421842
}
18431843

@@ -1858,7 +1858,7 @@ static int _dns_server_force_dualstack(struct dns_request *request)
18581858
/* if another request still waiting for ping, force complete another request */
18591859
_dns_server_check_complete_dualstack(request, dualstack_request);
18601860
}
1861-
1861+
18621862
if (request->dualstack_selection_ping_time < 0 || request->dualstack_selection == 0) {
18631863
return -1;
18641864
}
@@ -3113,7 +3113,7 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
31133113
char cname[DNS_MAX_CNAME_LEN];
31143114
char name[DNS_MAX_CNAME_LEN] = {0};
31153115
dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
3116-
tlog(TLOG_DEBUG, "NS: %s ttl: %d cname: %s\n", name, ttl, cname);
3116+
tlog(TLOG_DEBUG, "NS: %s, ttl: %d, cname: %s\n", name, ttl, cname);
31173117
} break;
31183118
case DNS_T_CNAME: {
31193119
char cname[DNS_MAX_CNAME_LEN];
@@ -3123,7 +3123,7 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
31233123
}
31243124

31253125
dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
3126-
tlog(TLOG_DEBUG, "name: %s ttl: %d cname: %s\n", name, ttl, cname);
3126+
tlog(TLOG_DEBUG, "name: %s, ttl: %d, cname: %s\n", name, ttl, cname);
31273127
if (strncmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 &&
31283128
strncmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) {
31293129
continue;
@@ -3762,7 +3762,7 @@ static int _dns_server_get_rules(unsigned char *key, uint32_t key_len, int is_su
37623762
return 0;
37633763
}
37643764

3765-
static void _dns_server_get_domain_rule(struct dns_request *request)
3765+
static void _dns_server_get_domain_rule_by_domain(struct dns_request *request, const char *domain, int out_log)
37663766
{
37673767
int domain_len = 0;
37683768
char domain_key[DNS_MAX_CNAME_LEN];
@@ -3779,8 +3779,8 @@ static void _dns_server_get_domain_rule(struct dns_request *request)
37793779
walk_args.args = request;
37803780

37813781
/* reverse domain string */
3782-
domain_len = strlen(request->domain);
3783-
reverse_string(domain_key, request->domain, domain_len, 1);
3782+
domain_len = strlen(domain);
3783+
reverse_string(domain_key, domain, domain_len, 1);
37843784
domain_key[domain_len] = '.';
37853785
domain_len++;
37863786
domain_key[domain_len] = 0;
@@ -3807,12 +3807,19 @@ static void _dns_server_get_domain_rule(struct dns_request *request)
38073807

38083808
matched_key_len--;
38093809
matched_key[matched_key_len] = 0;
3810-
_dns_server_log_rule(request->domain, i, matched_key, matched_key_len);
3810+
if (out_log != 0) {
3811+
_dns_server_log_rule(request->domain, i, matched_key, matched_key_len);
3812+
}
38113813
}
38123814

38133815
request->skip_domain_rule = 1;
38143816
}
38153817

3818+
static void _dns_server_get_domain_rule(struct dns_request *request)
3819+
{
3820+
_dns_server_get_domain_rule_by_domain(request, request->domain, 1);
3821+
}
3822+
38163823
static int _dns_server_pre_process_rule_flags(struct dns_request *request)
38173824
{
38183825
struct dns_rule_flags *rule_flag = NULL;
@@ -3977,7 +3984,7 @@ static int _dns_server_request_copy(struct dns_request *request, struct dns_requ
39773984

39783985
if (from->has_ip) {
39793986
request->has_ip = 1;
3980-
request->ip_ttl = from->ip_ttl;
3987+
request->ip_ttl = _dns_server_get_conf_ttl(request, from->ip_ttl);
39813988
request->ping_time = from->ping_time;
39823989
memcpy(request->ip_addr, from->ip_addr, sizeof(request->ip_addr));
39833990
}
@@ -4038,29 +4045,51 @@ static DNS_CHILD_POST_RESULT _dns_server_process_cname_callback(struct dns_reque
40384045
struct dns_request *child_request, int is_first_resp)
40394046
{
40404047
_dns_server_request_copy(request, child_request);
4041-
if (child_request->rcode == DNS_RC_NOERROR && dns_conf_force_no_cname == 0) {
4048+
if (child_request->rcode == DNS_RC_NOERROR && dns_conf_force_no_cname == 0 && child_request->has_soa == 0) {
40424049
safe_strncpy(request->cname, child_request->domain, sizeof(request->cname));
40434050
request->has_cname = 1;
4044-
request->ttl_cname = child_request->ip_ttl;
4051+
request->ttl_cname = _dns_server_get_conf_ttl(request, child_request->ip_ttl);
40454052
}
40464053

4047-
request->no_select_possible_ip = 1;
4048-
request->no_cache_cname = 1;
4054+
return DNS_CHILD_POST_SUCCESS;
4055+
}
40494056

4050-
/* copy child rules to parent */
4051-
for (int i = 0; i < DOMAIN_RULE_MAX; i++) {
4052-
if (request->domain_rule.rules[i] != NULL) {
4053-
continue;
4054-
}
4057+
static int _dns_server_process_cname_pre(struct dns_request *request)
4058+
{
4059+
struct dns_cname_rule *cname = NULL;
4060+
struct dns_rule_flags *rule_flag = NULL;
4061+
struct dns_domain_rule domain_rule;
40554062

4056-
if (child_request->domain_rule.rules[i] == NULL) {
4057-
continue;
4063+
if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_RULE_CNAME) == 0) {
4064+
return 0;
4065+
}
4066+
4067+
/* get domain rule flag */
4068+
rule_flag = _dns_server_get_dns_rule(request, DOMAIN_RULE_FLAGS);
4069+
if (rule_flag != NULL) {
4070+
if (rule_flag->flags & DOMAIN_FLAG_CNAME_IGN) {
4071+
return 0;
40584072
}
4073+
}
40594074

4060-
request->domain_rule.rules[i] = child_request->domain_rule.rules[i];
4075+
cname = _dns_server_get_dns_rule(request, DOMAIN_RULE_CNAME);
4076+
if (cname == NULL) {
4077+
return 0;
40614078
}
40624079

4063-
return DNS_CHILD_POST_SUCCESS;
4080+
request->skip_domain_rule = 0;
4081+
/* copy child rules */
4082+
memcpy(&domain_rule, &request->domain_rule, sizeof(domain_rule));
4083+
memset(&request->domain_rule, 0, sizeof(request->domain_rule));
4084+
_dns_server_get_domain_rule_by_domain(request, cname->cname, 0);
4085+
request->domain_rule.rules[DOMAIN_RULE_CNAME] = domain_rule.rules[DOMAIN_RULE_CNAME];
4086+
request->domain_rule.is_sub_rule[DOMAIN_RULE_CNAME] = domain_rule.is_sub_rule[DOMAIN_RULE_CNAME];
4087+
4088+
request->no_select_possible_ip = 1;
4089+
request->no_cache_cname = 1;
4090+
safe_strncpy(request->cname, cname->cname, sizeof(request->cname));
4091+
4092+
return 0;
40644093
}
40654094

40664095
static int _dns_server_process_cname(struct dns_request *request)
@@ -4082,11 +4111,6 @@ static int _dns_server_process_cname(struct dns_request *request)
40824111
}
40834112
}
40844113

4085-
/* cname /domain/ rule */
4086-
if (request->domain_rule.rules[DOMAIN_RULE_CNAME] == NULL) {
4087-
return 0;
4088-
}
4089-
40904114
cname = _dns_server_get_dns_rule(request, DOMAIN_RULE_CNAME);
40914115
if (cname == NULL) {
40924116
return 0;
@@ -4461,9 +4485,13 @@ static int _dns_server_process_cache(struct dns_request *request)
44614485

44624486
cache_key.qtype = dualstack_qtype;
44634487
dualstack_dns_cache = dns_cache_lookup(&cache_key);
4488+
if (dualstack_dns_cache == NULL && request->cname[0] != '\0') {
4489+
cache_key.domain = request->cname;
4490+
dualstack_dns_cache = dns_cache_lookup(&cache_key);
4491+
}
4492+
44644493
if (dualstack_dns_cache && dns_cache_is_soa(dualstack_dns_cache) == 0 &&
44654494
(dualstack_dns_cache->info.speed > 0)) {
4466-
44674495
if (dns_cache_is_soa(dns_cache)) {
44684496
ret = _dns_server_process_cache_packet(request, dns_cache);
44694497
goto out_update_cache;
@@ -4885,6 +4913,10 @@ static int _dns_server_do_query(struct dns_request *request, int skip_notify_eve
48854913
safe_strncpy(request->dns_group_name, group_name, DNS_GROUP_NAME_LEN);
48864914
}
48874915

4916+
if (_dns_server_process_cname_pre(request) != 0) {
4917+
goto errout;
4918+
}
4919+
48884920
_dns_server_set_dualstack_selection(request);
48894921

48904922
if (_dns_server_process_special_query(request) == 0) {

0 commit comments

Comments
 (0)