dns-server: fix dns64 issue & cname dns-group-issue
This commit is contained in:
@@ -2186,6 +2186,11 @@ static int _dns_client_process_udp_proxy(struct dns_server_info *server_info, st
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int latency = get_tick_count() - server_info->send_tick;
|
||||||
|
if (latency < server_info->drop_packet_latency_ms) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
tlog(TLOG_DEBUG, "recv udp packet from %s, len: %d",
|
tlog(TLOG_DEBUG, "recv udp packet from %s, len: %d",
|
||||||
get_host_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), len);
|
get_host_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), len);
|
||||||
|
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ struct dns_request {
|
|||||||
DECLARE_HASHTABLE(ip_map, 4);
|
DECLARE_HASHTABLE(ip_map, 4);
|
||||||
|
|
||||||
struct dns_domain_rule domain_rule;
|
struct dns_domain_rule 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;
|
||||||
|
|
||||||
@@ -298,6 +299,7 @@ static int _dns_server_do_query(struct dns_request *request, int skip_notify_eve
|
|||||||
static int _dns_request_post(struct dns_server_post_context *context);
|
static int _dns_request_post(struct dns_server_post_context *context);
|
||||||
static int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_server_post_context *context);
|
static int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_server_post_context *context);
|
||||||
static void *_dns_server_get_dns_rule(struct dns_request *request, enum domain_rule rule);
|
static void *_dns_server_get_dns_rule(struct dns_request *request, enum domain_rule rule);
|
||||||
|
static const char *_dns_server_get_request_groupname(struct dns_request *request);
|
||||||
|
|
||||||
static void _dns_server_wakeup_thread(void)
|
static void _dns_server_wakeup_thread(void)
|
||||||
{
|
{
|
||||||
@@ -388,6 +390,23 @@ static int _dns_server_is_dns_rule_extract_match(struct dns_request *request, en
|
|||||||
return request->domain_rule.is_sub_rule[rule] == 0;
|
return request->domain_rule.is_sub_rule[rule] == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _dns_server_is_dns64_request(struct dns_request *request)
|
||||||
|
{
|
||||||
|
if (request->qtype != DNS_T_AAAA) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request->dualstack_selection_query == 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dns_conf_dns_dns64.prefix_len <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void _dns_server_set_dualstack_selection(struct dns_request *request)
|
static void _dns_server_set_dualstack_selection(struct dns_request *request)
|
||||||
{
|
{
|
||||||
struct dns_rule_flags *rule_flag = NULL;
|
struct dns_rule_flags *rule_flag = NULL;
|
||||||
@@ -1769,7 +1788,7 @@ static int _dns_server_reply_all_pending_list(struct dns_request *request, struc
|
|||||||
context_pending.do_force_soa = context->do_force_soa;
|
context_pending.do_force_soa = context->do_force_soa;
|
||||||
context_pending.do_ipset = 0;
|
context_pending.do_ipset = 0;
|
||||||
context_pending.reply_ttl = request->ip_ttl;
|
context_pending.reply_ttl = request->ip_ttl;
|
||||||
context_pending.no_release_parent = context->no_release_parent;
|
context_pending.no_release_parent = 0;
|
||||||
_dns_server_reply_passthrough(&context_pending);
|
_dns_server_reply_passthrough(&context_pending);
|
||||||
|
|
||||||
req->request_pending_list = NULL;
|
req->request_pending_list = NULL;
|
||||||
@@ -2786,9 +2805,14 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
|
|||||||
}
|
}
|
||||||
safe_strncpy(cname, domain_cname, DNS_MAX_CNAME_LEN);
|
safe_strncpy(cname, domain_cname, DNS_MAX_CNAME_LEN);
|
||||||
request->ttl_cname = _dns_server_get_conf_ttl(request, ttl);
|
request->ttl_cname = _dns_server_get_conf_ttl(request, ttl);
|
||||||
tlog(TLOG_DEBUG, "name: %s ttl: %d cname: %s\n", name, ttl, cname);
|
tlog(TLOG_DEBUG, "name: %s ttl: %d cname: %s\n", domain_name, ttl, cname);
|
||||||
} break;
|
} break;
|
||||||
case DNS_T_SOA: {
|
case DNS_T_SOA: {
|
||||||
|
/* if DNS64 enabled, skip check SOA. */
|
||||||
|
if (_dns_server_is_dns64_request(request)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
request->has_soa = 1;
|
request->has_soa = 1;
|
||||||
if (request->rcode != DNS_RC_NOERROR) {
|
if (request->rcode != DNS_RC_NOERROR) {
|
||||||
request->rcode = packet->head.rcode;
|
request->rcode = packet->head.rcode;
|
||||||
@@ -2800,11 +2824,6 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
|
|||||||
domain, request->qtype, request->soa.mname, request->soa.rname, request->soa.serial,
|
domain, request->qtype, request->soa.mname, request->soa.rname, request->soa.serial,
|
||||||
request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum);
|
request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum);
|
||||||
|
|
||||||
/* if DNS64 enabled, skip check SOA. */
|
|
||||||
if (request->qtype == DNS_T_AAAA && dns_conf_dns_dns64.prefix_len > 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int soa_num = atomic_inc_return(&request->soa_num);
|
int soa_num = atomic_inc_return(&request->soa_num);
|
||||||
if ((soa_num >= (dns_server_num() / 3) + 1 || soa_num > 4) && atomic_read(&request->ip_map_num) <= 0) {
|
if ((soa_num >= (dns_server_num() / 3) + 1 || soa_num > 4) && atomic_read(&request->ip_map_num) <= 0) {
|
||||||
request->ip_ttl = ttl;
|
request->ip_ttl = ttl;
|
||||||
@@ -3139,7 +3158,12 @@ static void _dns_server_query_end(struct dns_request *request)
|
|||||||
/* Not need to wait check result if only has one ip address */
|
/* Not need to wait check result if only has one ip address */
|
||||||
if (ip_num == 1 && request_wait == 1) {
|
if (ip_num == 1 && request_wait == 1) {
|
||||||
if (request->dualstack_selection_query == 1) {
|
if (request->dualstack_selection_query == 1) {
|
||||||
_dns_server_request_complete(request);
|
if ((dns_conf_ipset_no_speed.ipv4_enable || dns_conf_nftset_no_speed.ip6_enable ||
|
||||||
|
dns_conf_ipset_no_speed.ipv6_enable || dns_conf_nftset_no_speed.ip6_enable) &&
|
||||||
|
dns_conf_dns_dns64.prefix_len == 0) {
|
||||||
|
/* if speed check fail enabled, we need reply quickly, otherwise wait for ping result.*/
|
||||||
|
_dns_server_request_complete(request);
|
||||||
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3696,6 +3720,10 @@ static void _dns_server_get_domain_rule(struct dns_request *request)
|
|||||||
struct rule_walk_args walk_args;
|
struct rule_walk_args walk_args;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
if (request->skip_domain_rule != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&walk_args, 0, sizeof(walk_args));
|
memset(&walk_args, 0, sizeof(walk_args));
|
||||||
walk_args.args = request;
|
walk_args.args = request;
|
||||||
|
|
||||||
@@ -3730,6 +3758,8 @@ static void _dns_server_get_domain_rule(struct dns_request *request)
|
|||||||
matched_key[matched_key_len] = 0;
|
matched_key[matched_key_len] = 0;
|
||||||
_dns_server_log_rule(request->domain, i, matched_key, matched_key_len);
|
_dns_server_log_rule(request->domain, i, matched_key, matched_key_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request->skip_domain_rule = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dns_server_pre_process_rule_flags(struct dns_request *request)
|
static int _dns_server_pre_process_rule_flags(struct dns_request *request)
|
||||||
@@ -3846,8 +3876,8 @@ errout:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dns_request *_dns_server_new_child_request(struct dns_request *request,
|
static struct dns_request *_dns_server_new_child_request(struct dns_request *request, const char *domain,
|
||||||
child_request_callback child_callback)
|
dns_type_t qtype, child_request_callback child_callback)
|
||||||
{
|
{
|
||||||
struct dns_request *child_request = NULL;
|
struct dns_request *child_request = NULL;
|
||||||
|
|
||||||
@@ -3859,10 +3889,14 @@ static struct dns_request *_dns_server_new_child_request(struct dns_request *req
|
|||||||
|
|
||||||
child_request->server_flags = request->server_flags;
|
child_request->server_flags = request->server_flags;
|
||||||
safe_strncpy(child_request->dns_group_name, request->dns_group_name, sizeof(request->dns_group_name));
|
safe_strncpy(child_request->dns_group_name, request->dns_group_name, sizeof(request->dns_group_name));
|
||||||
|
safe_strncpy(child_request->domain, domain, sizeof(child_request->domain));
|
||||||
child_request->prefetch = request->prefetch;
|
child_request->prefetch = request->prefetch;
|
||||||
child_request->prefetch_expired_domain = request->prefetch_expired_domain;
|
child_request->prefetch_expired_domain = request->prefetch_expired_domain;
|
||||||
child_request->child_callback = child_callback;
|
child_request->child_callback = child_callback;
|
||||||
child_request->parent_request = request;
|
child_request->parent_request = request;
|
||||||
|
child_request->qtype = qtype;
|
||||||
|
child_request->qclass = request->qclass;
|
||||||
|
|
||||||
if (request->has_ecs) {
|
if (request->has_ecs) {
|
||||||
memcpy(&child_request->ecs, &request->ecs, sizeof(child_request->ecs));
|
memcpy(&child_request->ecs, &request->ecs, sizeof(child_request->ecs));
|
||||||
child_request->has_ecs = request->has_ecs;
|
child_request->has_ecs = request->has_ecs;
|
||||||
@@ -3870,6 +3904,7 @@ static struct dns_request *_dns_server_new_child_request(struct dns_request *req
|
|||||||
_dns_server_request_get(request);
|
_dns_server_request_get(request);
|
||||||
/* reference count is 1 hold by parent request */
|
/* reference count is 1 hold by parent request */
|
||||||
request->child_request = child_request;
|
request->child_request = child_request;
|
||||||
|
_dns_server_get_domain_rule(child_request);
|
||||||
return child_request;
|
return child_request;
|
||||||
errout:
|
errout:
|
||||||
if (child_request) {
|
if (child_request) {
|
||||||
@@ -3952,7 +3987,11 @@ static DNS_CHILD_POST_RESULT _dns_server_process_cname_callback(struct dns_reque
|
|||||||
struct dns_request *child_request, int is_first_resp)
|
struct dns_request *child_request, int is_first_resp)
|
||||||
{
|
{
|
||||||
_dns_server_request_copy(request, child_request);
|
_dns_server_request_copy(request, child_request);
|
||||||
safe_strncpy(request->cname, child_request->domain, sizeof(request->cname));
|
if (child_request->rcode == DNS_RC_NOERROR) {
|
||||||
|
safe_strncpy(request->cname, child_request->domain, sizeof(request->cname));
|
||||||
|
request->has_cname = 1;
|
||||||
|
request->ttl_cname = child_request->ip_ttl;
|
||||||
|
}
|
||||||
|
|
||||||
return DNS_CHILD_POST_SUCCESS;
|
return DNS_CHILD_POST_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -3960,6 +3999,7 @@ static DNS_CHILD_POST_RESULT _dns_server_process_cname_callback(struct dns_reque
|
|||||||
static int _dns_server_process_cname(struct dns_request *request)
|
static int _dns_server_process_cname(struct dns_request *request)
|
||||||
{
|
{
|
||||||
struct dns_cname_rule *cname = NULL;
|
struct dns_cname_rule *cname = NULL;
|
||||||
|
const char *child_group_name = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct dns_rule_flags *rule_flag = NULL;
|
struct dns_rule_flags *rule_flag = NULL;
|
||||||
|
|
||||||
@@ -3987,15 +4027,18 @@ static int _dns_server_process_cname(struct dns_request *request)
|
|||||||
|
|
||||||
tlog(TLOG_INFO, "query %s with cname %s", request->domain, cname->cname);
|
tlog(TLOG_INFO, "query %s with cname %s", request->domain, cname->cname);
|
||||||
|
|
||||||
struct dns_request *child_request = _dns_server_new_child_request(request, _dns_server_process_cname_callback);
|
struct dns_request *child_request =
|
||||||
|
_dns_server_new_child_request(request, cname->cname, request->qtype, _dns_server_process_cname_callback);
|
||||||
if (child_request == NULL) {
|
if (child_request == NULL) {
|
||||||
tlog(TLOG_ERROR, "malloc failed.\n");
|
tlog(TLOG_ERROR, "malloc failed.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
child_request->qtype = request->qtype;
|
child_group_name = _dns_server_get_request_groupname(child_request);
|
||||||
child_request->qclass = request->qclass;
|
if (child_group_name) {
|
||||||
safe_strncpy(child_request->domain, cname->cname, sizeof(child_request->cname));
|
/* reset dns group and setup child request domain group again when do query.*/
|
||||||
|
child_request->dns_group_name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
request->request_wait++;
|
request->request_wait++;
|
||||||
ret = _dns_server_do_query(child_request, 0);
|
ret = _dns_server_do_query(child_request, 0);
|
||||||
@@ -4037,6 +4080,12 @@ _dns_server_process_dns64_callback(struct dns_request *request, struct dns_reque
|
|||||||
return DNS_CHILD_POST_FAIL;
|
return DNS_CHILD_POST_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (child_request->has_cname == 1) {
|
||||||
|
safe_strncpy(request->cname, child_request->cname, sizeof(request->cname));
|
||||||
|
request->has_cname = 1;
|
||||||
|
request->ttl_cname = child_request->ttl_cname;
|
||||||
|
}
|
||||||
|
|
||||||
if (child_request->has_ip == 0) {
|
if (child_request->has_ip == 0) {
|
||||||
if (child_request->has_soa) {
|
if (child_request->has_soa) {
|
||||||
memcpy(&request->soa, &child_request->soa, sizeof(struct dns_soa));
|
memcpy(&request->soa, &child_request->soa, sizeof(struct dns_soa));
|
||||||
@@ -4108,27 +4157,19 @@ _dns_server_process_dns64_callback(struct dns_request *request, struct dns_reque
|
|||||||
|
|
||||||
static int _dns_server_process_dns64(struct dns_request *request)
|
static int _dns_server_process_dns64(struct dns_request *request)
|
||||||
{
|
{
|
||||||
if (request->qtype != DNS_T_AAAA) {
|
if (_dns_server_is_dns64_request(request) == 0) {
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dns_conf_dns_dns64.prefix_len <= 0) {
|
|
||||||
/* no dns64 prefix, no need to do dns64 */
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tlog(TLOG_DEBUG, "query %s with dns64", request->domain);
|
tlog(TLOG_DEBUG, "query %s with dns64", request->domain);
|
||||||
|
|
||||||
struct dns_request *child_request = _dns_server_new_child_request(request, _dns_server_process_dns64_callback);
|
struct dns_request *child_request =
|
||||||
|
_dns_server_new_child_request(request, request->domain, DNS_T_A, _dns_server_process_dns64_callback);
|
||||||
if (child_request == NULL) {
|
if (child_request == NULL) {
|
||||||
tlog(TLOG_ERROR, "malloc failed.\n");
|
tlog(TLOG_ERROR, "malloc failed.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
child_request->qtype = DNS_T_A;
|
|
||||||
child_request->qclass = request->qclass;
|
|
||||||
safe_strncpy(child_request->domain, request->domain, sizeof(child_request->domain));
|
|
||||||
|
|
||||||
request->request_wait++;
|
request->request_wait++;
|
||||||
int ret = _dns_server_do_query(child_request, 0);
|
int ret = _dns_server_do_query(child_request, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@@ -4305,7 +4346,6 @@ static int _dns_server_process_cache_data(struct dns_request *request, struct dn
|
|||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto out;
|
goto out;
|
||||||
@@ -4705,7 +4745,7 @@ static int _dns_server_query_dualstack(struct dns_request *request)
|
|||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
struct dns_request *request_dualstack = NULL;
|
struct dns_request *request_dualstack = NULL;
|
||||||
int qtype = request->qtype;
|
dns_type_t qtype = request->qtype;
|
||||||
|
|
||||||
if (request->dualstack_selection == 0) {
|
if (request->dualstack_selection == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user