ecs: support pass client ecs to upstream

This commit is contained in:
Nick Peng
2022-05-26 23:03:40 +08:00
parent b125d142bd
commit b5a5311976
4 changed files with 261 additions and 93 deletions

View File

@@ -887,11 +887,12 @@ int dns_add_OPT_ECS(struct dns_packet *packet, struct dns_opt_ecs *ecs)
int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt_ecs *ecs) int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt_ecs *ecs)
{ {
unsigned char opt_data[DNS_MAX_OPT_LEN]; unsigned char opt_data[DNS_MAX_OPT_LEN];
char domain[DNS_MAX_CNAME_LEN] = {0};
struct dns_opt *opt = (struct dns_opt *)opt_data; struct dns_opt *opt = (struct dns_opt *)opt_data;
int len = DNS_MAX_OPT_LEN; int len = DNS_MAX_OPT_LEN;
int ttl = 0; int ttl = 0;
if (_dns_get_RAW(rrs, NULL, 0, &ttl, opt_data, &len) != 0) { if (_dns_get_RAW(rrs, domain, DNS_MAX_CNAME_LEN, &ttl, opt_data, &len) != 0) {
return -1; return -1;
} }

View File

@@ -66,13 +66,7 @@
/* ECS info */ /* ECS info */
struct dns_client_ecs { struct dns_client_ecs {
int enable; int enable;
unsigned int family; struct dns_opt_ecs ecs;
unsigned int bitlen;
union {
unsigned char ipv4_addr[DNS_RR_A_LEN];
unsigned char ipv6_addr[DNS_RR_AAAA_LEN];
unsigned char addr[0];
};
}; };
/* TCP/TLS buffer */ /* TCP/TLS buffer */
@@ -244,6 +238,9 @@ struct dns_query_struct {
/* has result */ /* has result */
int has_result; int has_result;
/* ECS */
struct dns_client_ecs ecs;
/* replied hash table */ /* replied hash table */
DECLARE_HASHTABLE(replied_map, 4); DECLARE_HASHTABLE(replied_map, 4);
}; };
@@ -2873,42 +2870,13 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
return 0; return 0;
} }
static int _dns_client_dns_add_ecs(struct dns_packet *packet, int qtype) static int _dns_client_dns_add_ecs(struct dns_query_struct *query, struct dns_packet *packet)
{ {
int add_ipv4_ecs = 0; if (query->ecs.enable == 0) {
int add_ipv6_ecs = 0; return 0;
if (qtype == DNS_T_A && client.ecs_ipv4.enable) {
add_ipv4_ecs = 1;
} else if (qtype == DNS_T_AAAA && client.ecs_ipv6.enable) {
add_ipv6_ecs = 1;
} else {
if (client.ecs_ipv4.enable) {
add_ipv4_ecs = 1;
} else if (client.ecs_ipv6.enable) {
add_ipv4_ecs = 1;
}
} }
if (add_ipv4_ecs) { return dns_add_OPT_ECS(packet, &query->ecs.ecs);
struct dns_opt_ecs ecs;
ecs.family = DNS_ADDR_FAMILY_IP;
ecs.source_prefix = client.ecs_ipv4.bitlen;
ecs.scope_prefix = 0;
memcpy(ecs.addr, client.ecs_ipv4.ipv4_addr, DNS_RR_A_LEN);
return dns_add_OPT_ECS(packet, &ecs);
}
if (add_ipv6_ecs) {
struct dns_opt_ecs ecs;
ecs.family = DNS_ADDR_FAMILY_IPV6;
ecs.source_prefix = client.ecs_ipv6.bitlen;
ecs.scope_prefix = 0;
memcpy(ecs.addr, client.ecs_ipv6.ipv6_addr, DNS_RR_AAAA_LEN);
return dns_add_OPT_ECS(packet, &ecs);
}
return 0;
} }
static int _dns_client_send_query(struct dns_query_struct *query, char *doamin) static int _dns_client_send_query(struct dns_query_struct *query, char *doamin)
@@ -2942,7 +2910,7 @@ static int _dns_client_send_query(struct dns_query_struct *query, char *doamin)
dns_set_OPT_payload_size(packet, DNS_IN_PACKSIZE); dns_set_OPT_payload_size(packet, DNS_IN_PACKSIZE);
/* dns_add_OPT_TCP_KEEYALIVE(packet, 600); */ /* dns_add_OPT_TCP_KEEYALIVE(packet, 600); */
if (_dns_client_dns_add_ecs(packet, query->qtype) != 0) { if (_dns_client_dns_add_ecs(query, packet) != 0) {
tlog(TLOG_ERROR, "add ecs failed."); tlog(TLOG_ERROR, "add ecs failed.");
return -1; return -1;
} }
@@ -2964,7 +2932,102 @@ static int _dns_client_send_query(struct dns_query_struct *query, char *doamin)
return _dns_client_send_packet(query, inpacket, encode_len); return _dns_client_send_packet(query, inpacket, encode_len);
} }
int dns_client_query(char *domain, int qtype, dns_client_callback callback, void *user_ptr, const char *group_name) int _dns_client_query_setup_default_ecs(struct dns_query_struct *query)
{
int add_ipv4_ecs = 0;
int add_ipv6_ecs = 0;
if (query->qtype == DNS_T_A && client.ecs_ipv4.enable) {
add_ipv4_ecs = 1;
} else if (query->qtype == DNS_T_AAAA && client.ecs_ipv6.enable) {
add_ipv6_ecs = 1;
} else {
if (client.ecs_ipv4.enable) {
add_ipv4_ecs = 1;
} else if (client.ecs_ipv6.enable) {
add_ipv4_ecs = 1;
}
}
if (add_ipv4_ecs) {
memcpy(&query->ecs, &client.ecs_ipv4, sizeof(query->ecs));
return 0;
}
if (add_ipv6_ecs) {
memcpy(&query->ecs, &client.ecs_ipv6, sizeof(query->ecs));
return 0;
}
return 0;
}
int _dns_client_query_parser_options(struct dns_query_struct *query, struct dns_query_options *options)
{
if (options == NULL) {
_dns_client_query_setup_default_ecs(query);
return 0;
}
if (options->enable_flag & DNS_QUEY_OPTION_ECS_IP) {
struct sockaddr_storage addr;
socklen_t addr_len = sizeof(addr);
struct dns_opt_ecs *ecs;
ecs = &query->ecs.ecs;
getaddr_by_host(options->ecs_ip.ip, (struct sockaddr *)&addr, &addr_len);
query->ecs.enable = 1;
ecs->source_prefix = options->ecs_ip.subnet;
ecs->scope_prefix = 0;
switch (addr.ss_family) {
case AF_INET: {
struct sockaddr_in *addr_in;
addr_in = (struct sockaddr_in *)&addr;
ecs->family = DNS_OPT_ECS_FAMILY_IPV4;
memcpy(&ecs->addr, &addr_in->sin_addr.s_addr, 4);
} break;
case AF_INET6: {
struct sockaddr_in6 *addr_in6;
addr_in6 = (struct sockaddr_in6 *)&addr;
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
memcpy(&ecs->addr, addr_in6->sin6_addr.s6_addr + 12, 4);
ecs->family = DNS_OPT_ECS_FAMILY_IPV4;
} else {
memcpy(&ecs->addr, addr_in6->sin6_addr.s6_addr, 16);
ecs->family = DNS_OPT_ECS_FAMILY_IPV6;
}
} break;
default:
tlog(TLOG_WARN, "ECS set failure.");
break;
}
}
if (options->enable_flag & DNS_QUEY_OPTION_ECS_DNS) {
struct dns_opt_ecs *ecs = &options->ecs_dns;
if (ecs->family != DNS_OPT_ECS_FAMILY_IPV6 && ecs->family != DNS_OPT_ECS_FAMILY_IPV4) {
return -1;
}
if (ecs->family == DNS_OPT_ECS_FAMILY_IPV4 && ecs->source_prefix > 32) {
return -1;
}
if (ecs->family == DNS_OPT_ECS_FAMILY_IPV6 && ecs->source_prefix > 128) {
return -1;
}
memcpy(&query->ecs.ecs, ecs, sizeof(query->ecs.ecs));
query->ecs.enable = 1;
}
return 0;
}
int dns_client_query(char *domain, int qtype, dns_client_callback callback, void *user_ptr, const char *group_name,
struct dns_query_options *options)
{ {
struct dns_query_struct *query = NULL; struct dns_query_struct *query = NULL;
int ret = 0; int ret = 0;
@@ -2999,6 +3062,11 @@ int dns_client_query(char *domain, int qtype, dns_client_callback callback, void
goto errout; goto errout;
} }
if (_dns_client_query_parser_options(query, options) != 0) {
tlog(TLOG_ERROR, "parser options for %s failed.", domain);
goto errout;
}
_dns_client_query_get(query); _dns_client_query_get(query);
/* add query to hashtable */ /* add query to hashtable */
key = hash_string(domain); key = hash_string(domain);
@@ -3299,20 +3367,25 @@ int dns_client_set_ecs(char *ip, int subnet)
case AF_INET: { case AF_INET: {
struct sockaddr_in *addr_in; struct sockaddr_in *addr_in;
addr_in = (struct sockaddr_in *)&addr; addr_in = (struct sockaddr_in *)&addr;
memcpy(&client.ecs_ipv4.ipv4_addr, &addr_in->sin_addr.s_addr, 4); memcpy(&client.ecs_ipv4.ecs.addr, &addr_in->sin_addr.s_addr, 4);
client.ecs_ipv4.bitlen = subnet; client.ecs_ipv4.ecs.source_prefix = subnet;
client.ecs_ipv4.ecs.scope_prefix = 0;
client.ecs_ipv4.ecs.family = DNS_OPT_ECS_FAMILY_IPV4;
client.ecs_ipv4.enable = 1; client.ecs_ipv4.enable = 1;
} break; } break;
case AF_INET6: { case AF_INET6: {
struct sockaddr_in6 *addr_in6; struct sockaddr_in6 *addr_in6;
addr_in6 = (struct sockaddr_in6 *)&addr; addr_in6 = (struct sockaddr_in6 *)&addr;
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) { if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
memcpy(&client.ecs_ipv4.ipv4_addr, addr_in6->sin6_addr.s6_addr + 12, 4); client.ecs_ipv4.ecs.source_prefix = subnet;
client.ecs_ipv4.bitlen = subnet; client.ecs_ipv4.ecs.scope_prefix = 0;
client.ecs_ipv4.ecs.family = DNS_OPT_ECS_FAMILY_IPV4;
client.ecs_ipv4.enable = 1; client.ecs_ipv4.enable = 1;
} else { } else {
memcpy(&client.ecs_ipv6.ipv6_addr, addr_in6->sin6_addr.s6_addr, 16); memcpy(&client.ecs_ipv6.ecs.addr, addr_in6->sin6_addr.s6_addr, 16);
client.ecs_ipv6.bitlen = subnet; client.ecs_ipv6.ecs.source_prefix = subnet;
client.ecs_ipv6.ecs.scope_prefix = 0;
client.ecs_ipv6.ecs.family = DNS_ADDR_FAMILY_IPV6;
client.ecs_ipv6.enable = 1; client.ecs_ipv6.enable = 1;
} }
} break; } break;

View File

@@ -47,6 +47,9 @@ typedef enum dns_result_type {
#define DNSSERVER_FLAG_CHECK_EDNS (0x1 << 2) #define DNSSERVER_FLAG_CHECK_EDNS (0x1 << 2)
#define DNSSERVER_FLAG_CHECK_TTL (0x1 << 3) #define DNSSERVER_FLAG_CHECK_TTL (0x1 << 3)
#define DNS_QUEY_OPTION_ECS_DNS (1 << 0)
#define DNS_QUEY_OPTION_ECS_IP (1 << 1)
int dns_client_init(void); int dns_client_init(void);
int dns_client_set_ecs(char *ip, int subnet); int dns_client_set_ecs(char *ip, int subnet);
@@ -56,8 +59,20 @@ typedef int (*dns_client_callback)(char *domain, dns_result_type rtype, unsigned
struct dns_packet *packet, unsigned char *inpacket, int inpacket_len, struct dns_packet *packet, unsigned char *inpacket, int inpacket_len,
void *user_ptr); void *user_ptr);
struct dns_query_ecs_ip {
char ip[DNS_MAX_CNAME_LEN];
int subnet;
};
struct dns_query_options {
unsigned long long enable_flag;
struct dns_opt_ecs ecs_dns;
struct dns_query_ecs_ip ecs_ip;
};
/* query domain */ /* query domain */
int dns_client_query(char *domain, int qtype, dns_client_callback callback, void *user_ptr, const char *group_name); int dns_client_query(char *domain, int qtype, dns_client_callback callback, void *user_ptr, const char *group_name,
struct dns_query_options *options);
void dns_client_exit(void); void dns_client_exit(void);

View File

@@ -184,6 +184,8 @@ struct dns_request {
struct sockaddr addr; struct sockaddr addr;
}; };
struct sockaddr_storage localaddr; struct sockaddr_storage localaddr;
int has_ecs;
struct dns_opt_ecs ecs;
dns_result_callback result_callback; dns_result_callback result_callback;
void *user_ptr; void *user_ptr;
@@ -252,7 +254,7 @@ static tlog_log *dns_audit;
static int is_ipv6_ready; static int is_ipv6_ready;
static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, uint32_t server_flags); static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, uint32_t server_flags, struct dns_query_options *options);
static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len) static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len)
{ {
@@ -685,6 +687,10 @@ static int _dns_add_rrs(struct dns_server_post_context *context)
_dns_server_setup_soa(request); _dns_server_setup_soa(request);
ret |= dns_add_SOA(context->packet, DNS_RRS_NS, domain, 0, &request->soa); ret |= dns_add_SOA(context->packet, DNS_RRS_NS, domain, 0, &request->soa);
} }
if (request->has_ecs) {
ret |= dns_add_OPT_ECS(context->packet, &request->ecs);
}
return ret; return ret;
} }
@@ -3346,10 +3352,17 @@ static int _dns_server_process_cache(struct dns_request *request)
out_update_cache: out_update_cache:
if (dns_cache_get_ttl(dns_cache) == 0) { if (dns_cache_get_ttl(dns_cache) == 0) {
uint32_t server_flags = request->server_flags; uint32_t server_flags = request->server_flags;
struct dns_query_options options;
if (request->conn == NULL) { if (request->conn == NULL) {
server_flags = dns_cache_get_cache_flag(dns_cache->cache_data); server_flags = dns_cache_get_cache_flag(dns_cache->cache_data);
} }
_dns_server_prefetch_request(request->domain, request->qtype, server_flags);
options.enable_flag = 0;
if (request->has_ecs) {
options.enable_flag |= DNS_QUEY_OPTION_ECS_DNS;
memcpy(&options.ecs_dns, &request->ecs, sizeof(options.ecs_dns));
}
_dns_server_prefetch_request(request->domain, request->qtype, server_flags, &options);
} else { } else {
dns_cache_update(dns_cache); dns_cache_update(dns_cache);
} }
@@ -3623,19 +3636,29 @@ errout:
return -1; return -1;
} }
static int _dns_server_do_query(struct dns_request *request, const char *domain, int qtype) static int _dns_server_setup_query_option(struct dns_request *request, struct dns_query_options *options)
{
options->enable_flag = 0;
if (request->has_ecs) {
memcpy(&options->ecs_dns, &request->ecs, sizeof(options->ecs_dns));
options->enable_flag |= DNS_QUEY_OPTION_ECS_DNS;
}
return 0;
}
static int _dns_server_do_query(struct dns_request *request)
{ {
int ret = -1; int ret = -1;
const char *group_name = NULL; const char *group_name = NULL;
const char *dns_group = NULL; const char *dns_group = NULL;
struct dns_query_options options;
if (request->conn) { if (request->conn) {
dns_group = request->conn->dns_group; dns_group = request->conn->dns_group;
} }
safe_strncpy(request->domain, domain, sizeof(request->domain));
request->qtype = qtype;
/* lookup domain rule */ /* lookup domain rule */
_dns_server_get_domain_rule(request); _dns_server_get_domain_rule(request);
group_name = _dns_server_get_request_groupname(request); group_name = _dns_server_get_request_groupname(request);
@@ -3686,6 +3709,9 @@ static int _dns_server_do_query(struct dns_request *request, const char *domain,
goto clean_exit; goto clean_exit;
} }
// setup options
_dns_server_setup_query_option(request, &options);
// Get reference for server thread // Get reference for server thread
_dns_server_request_get(request); _dns_server_request_get(request);
pthread_mutex_lock(&server.request_list_lock); pthread_mutex_lock(&server.request_list_lock);
@@ -3694,11 +3720,11 @@ static int _dns_server_do_query(struct dns_request *request, const char *domain,
request->send_tick = get_tick_count(); request->send_tick = get_tick_count();
/* When the dual stack ip preference is enabled, both A and AAAA records are requested. */ /* When the dual stack ip preference is enabled, both A and AAAA records are requested. */
if (qtype == DNS_T_AAAA && request->dualstack_selection) { if (request->qtype == DNS_T_AAAA && request->dualstack_selection) {
// Get reference for AAAA query // Get reference for AAAA query
_dns_server_request_get(request); _dns_server_request_get(request);
request->request_wait++; request->request_wait++;
if (dns_client_query(request->domain, DNS_T_A, dns_server_resolve_callback, request, group_name) != 0) { if (dns_client_query(request->domain, DNS_T_A, dns_server_resolve_callback, request, group_name, &options) != 0) {
request->request_wait--; request->request_wait--;
_dns_server_request_release(request); _dns_server_request_release(request);
} }
@@ -3707,7 +3733,7 @@ static int _dns_server_do_query(struct dns_request *request, const char *domain,
// Get reference for DNS query // Get reference for DNS query
request->request_wait++; request->request_wait++;
_dns_server_request_get(request); _dns_server_request_get(request);
if (dns_client_query(request->domain, qtype, dns_server_resolve_callback, request, group_name) != 0) { if (dns_client_query(request->domain, request->qtype, dns_server_resolve_callback, request, group_name, &options) != 0) {
request->request_wait--; request->request_wait--;
_dns_server_request_release(request); _dns_server_request_release(request);
tlog(TLOG_ERROR, "send dns request failed."); tlog(TLOG_ERROR, "send dns request failed.");
@@ -3722,6 +3748,60 @@ errout:
return ret; return ret;
} }
static int _dns_server_parser_request(struct dns_request *request, struct dns_packet *packet)
{
struct dns_rrs *rrs;
int rr_count = 0;
int i = 0;
int ret = 0;
int qclass;
int qtype = DNS_T_ALL;
char domain[DNS_MAX_CNAME_LEN];
if (packet->head.qr != DNS_QR_QUERY) {
goto errout;
}
/* get request domain and request qtype */
rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &rr_count);
if (rr_count > 1 || rr_count <= 0) {
goto errout;
}
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
ret = dns_get_domain(rrs, domain, sizeof(domain), &qtype, &qclass);
if (ret != 0) {
goto errout;
}
// Only support one question.
safe_strncpy(request->domain, domain, sizeof(request->domain));
request->qtype = qtype;
break;
}
/* get request opts */
rr_count = 0;
rrs = dns_get_rrs_start(packet, DNS_RRS_OPT, &rr_count);
if (rr_count <= 0) {
return 0;
}
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
ret = dns_get_OPT_ECS(rrs, NULL, NULL, &request->ecs);
if (ret != 0) {
continue;
}
request->has_ecs = 1;
break;
}
return 0;
errout:
return -1;
}
static int _dns_server_recv(struct dns_server_conn_head *conn, unsigned char *inpacket, int inpacket_len, static int _dns_server_recv(struct dns_server_conn_head *conn, unsigned char *inpacket, int inpacket_len,
struct sockaddr_storage *local, socklen_t local_len, struct sockaddr_storage *from, struct sockaddr_storage *local, socklen_t local_len, struct sockaddr_storage *from,
socklen_t from_len) socklen_t from_len)
@@ -3730,14 +3810,9 @@ static int _dns_server_recv(struct dns_server_conn_head *conn, unsigned char *in
int ret = -1; int ret = -1;
unsigned char packet_buff[DNS_PACKSIZE]; unsigned char packet_buff[DNS_PACKSIZE];
char name[DNS_MAX_CNAME_LEN]; char name[DNS_MAX_CNAME_LEN];
char domain[DNS_MAX_CNAME_LEN];
struct dns_packet *packet = (struct dns_packet *)packet_buff; struct dns_packet *packet = (struct dns_packet *)packet_buff;
struct dns_request *request = NULL; struct dns_request *request = NULL;
struct dns_rrs *rrs;
int rr_count = 0;
int i = 0;
int qclass;
int qtype = DNS_T_ALL;
/* decode packet */ /* decode packet */
tlog(TLOG_DEBUG, "recv query packet from %s, len = %d", tlog(TLOG_DEBUG, "recv query packet from %s, len = %d",
@@ -3754,40 +3829,25 @@ static int _dns_server_recv(struct dns_server_conn_head *conn, unsigned char *in
packet->head.qdcount, packet->head.ancount, packet->head.nscount, packet->head.nrcount, inpacket_len, packet->head.qdcount, packet->head.ancount, packet->head.nscount, packet->head.nrcount, inpacket_len,
packet->head.id, packet->head.tc, packet->head.rd, packet->head.ra, packet->head.rcode); packet->head.id, packet->head.tc, packet->head.rd, packet->head.ra, packet->head.rcode);
if (packet->head.qr != DNS_QR_QUERY) {
goto errout;
}
/* get request domain and request qtype */
rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &rr_count);
if (rr_count > 1) {
goto errout;
}
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
ret = dns_get_domain(rrs, domain, sizeof(domain), &qtype, &qclass);
if (ret != 0) {
goto errout;
}
// Only support one question.
break;
}
tlog(TLOG_INFO, "query server %s from %s, qtype = %d\n", domain, name, qtype);
request = _dns_server_new_request(); request = _dns_server_new_request();
if (request == NULL) { if (request == NULL) {
tlog(TLOG_ERROR, "malloc failed.\n"); tlog(TLOG_ERROR, "malloc failed.\n");
goto errout; goto errout;
} }
if (_dns_server_parser_request(request, packet) != 0) {
goto errout;
}
tlog(TLOG_INFO, "query server %s from %s, qtype = %d\n", request->domain, name, request->qtype);
memcpy(&request->localaddr, local, local_len); memcpy(&request->localaddr, local, local_len);
_dns_server_request_set_client(request, conn); _dns_server_request_set_client(request, conn);
_dns_server_request_set_client_addr(request, from, from_len); _dns_server_request_set_client_addr(request, from, from_len);
_dns_server_request_set_id(request, packet->head.id); _dns_server_request_set_id(request, packet->head.id);
ret = _dns_server_do_query(request, domain, qtype); ret = _dns_server_do_query(request);
if (ret != 0) { if (ret != 0) {
tlog(TLOG_ERROR, "do query %s failed.\n", domain); tlog(TLOG_ERROR, "do query %s failed.\n", request->domain);
goto errout; goto errout;
} }
_dns_server_request_release_complete(request, 0); _dns_server_request_release_complete(request, 0);
@@ -3801,7 +3861,21 @@ errout:
return ret; return ret;
} }
static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, uint32_t server_flags) static int _dns_server_prefetch_setup_options(struct dns_request *request, struct dns_query_options *options)
{
if (options == NULL) {
return 0;
}
if (options->enable_flag & DNS_QUEY_OPTION_ECS_DNS) {
request->has_ecs = 1;
memcpy(&request->ecs, &options->ecs_dns, sizeof(request->ecs));
}
return 0;
}
static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, uint32_t server_flags, struct dns_query_options *options)
{ {
int ret = -1; int ret = -1;
struct dns_request *request = NULL; struct dns_request *request = NULL;
@@ -3812,11 +3886,14 @@ static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, uint32_t
goto errout; goto errout;
} }
safe_strncpy(request->domain, domain, sizeof(request->domain));
request->qtype = qtype;
request->server_flags = server_flags; request->server_flags = server_flags;
_dns_server_prefetch_setup_options(request, options);
_dns_server_request_set_enable_prefetch(request); _dns_server_request_set_enable_prefetch(request);
ret = _dns_server_do_query(request, domain, qtype); ret = _dns_server_do_query(request);
if (ret != 0) { if (ret != 0) {
tlog(TLOG_ERROR, "do query %s failed.\n", domain); tlog(TLOG_ERROR, "do query %s failed.\n", request->domain);
goto errout; goto errout;
} }
@@ -3842,8 +3919,10 @@ int dns_server_query(char *domain, int qtype, uint32_t server_flags, dns_result_
} }
request->server_flags = server_flags; request->server_flags = server_flags;
safe_strncpy(request->domain, domain, sizeof(request->domain));
request->qtype = qtype;
_dns_server_request_set_callback(request, callback, user_ptr); _dns_server_request_set_callback(request, callback, user_ptr);
ret = _dns_server_do_query(request, domain, qtype); ret = _dns_server_do_query(request);
if (ret != 0) { if (ret != 0) {
tlog(TLOG_ERROR, "do query %s failed.\n", domain); tlog(TLOG_ERROR, "do query %s failed.\n", domain);
goto errout; goto errout;
@@ -4239,7 +4318,7 @@ static void _dns_server_prefetch_domain(struct dns_cache *dns_cache)
tlog(TLOG_DEBUG, "prefetch by cache %s, qtype %d, ttl %d, hitnum %d", dns_cache->info.domain, dns_cache->info.qtype, tlog(TLOG_DEBUG, "prefetch by cache %s, qtype %d, ttl %d, hitnum %d", dns_cache->info.domain, dns_cache->info.qtype,
dns_cache->info.ttl, hitnum); dns_cache->info.ttl, hitnum);
if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype,
dns_cache_get_cache_flag(dns_cache->cache_data)) != 0) { dns_cache_get_cache_flag(dns_cache->cache_data), NULL) != 0) {
tlog(TLOG_ERROR, "prefetch domain %s, qtype %d, failed.", dns_cache->info.domain, dns_cache->info.qtype); tlog(TLOG_ERROR, "prefetch domain %s, qtype %d, failed.", dns_cache->info.domain, dns_cache->info.qtype);
} }
} }