cache: cache NXDOMAIN records.
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
#define DNS_MAX_EVENTS 256
|
||||
#define IPV6_READY_CHECK_TIME 180
|
||||
#define DNS_SERVER_TMOUT_TTL (5 * 60)
|
||||
#define DNS_SERVER_FAIL_TTL (60)
|
||||
#define DNS_CONN_BUFF_SIZE 4096
|
||||
#define DNS_REQUEST_MAX_TIMEOUT 850
|
||||
#define DNS_PING_TIMEOUT (DNS_REQUEST_MAX_TIMEOUT)
|
||||
@@ -254,7 +255,8 @@ static tlog_log *dns_audit;
|
||||
|
||||
static int is_ipv6_ready;
|
||||
|
||||
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_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)
|
||||
{
|
||||
@@ -1005,8 +1007,7 @@ int _dns_cache_cname_packet(struct dns_server_post_context *context)
|
||||
if (inpacket_len <= 0) {
|
||||
return -1;
|
||||
}
|
||||
cache_packet =
|
||||
dns_cache_new_data_packet(request->server_flags, inpacket_buff, inpacket_len);
|
||||
cache_packet = dns_cache_new_data_packet(request->server_flags, inpacket_buff, inpacket_len);
|
||||
if (cache_packet == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1042,6 +1043,36 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _dns_cache_error_packet(struct dns_server_post_context *context)
|
||||
{
|
||||
struct dns_request *request = context->request;
|
||||
struct dns_cache_data *cache_packet =
|
||||
dns_cache_new_data_packet(request->server_flags, context->inpacket, context->inpacket_len);
|
||||
if (cache_packet == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if doing prefetch, update cache only */
|
||||
if (request->prefetch) {
|
||||
if (dns_cache_replace(request->domain, DNS_SERVER_FAIL_TTL, context->qtype, -1, cache_packet) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
} else {
|
||||
/* insert result to cache */
|
||||
if (dns_cache_insert(request->domain, DNS_SERVER_FAIL_TTL, context->qtype, -1, cache_packet) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
if (cache_packet) {
|
||||
dns_cache_data_free(cache_packet);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _dns_cache_reply_packet(struct dns_server_post_context *context)
|
||||
{
|
||||
struct dns_request *request = context->request;
|
||||
@@ -1050,6 +1081,10 @@ static int _dns_cache_reply_packet(struct dns_server_post_context *context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (context->packet->head.rcode == DNS_RC_SERVFAIL || context->packet->head.rcode == DNS_RC_NXDOMAIN) {
|
||||
return _dns_cache_error_packet(context);
|
||||
}
|
||||
|
||||
if (context->qtype != DNS_T_AAAA && context->qtype != DNS_T_A) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1072,7 +1107,6 @@ static int _dns_cache_reply_packet(struct dns_server_post_context *context)
|
||||
tlog(TLOG_WARN, "update packet cache failed.");
|
||||
}
|
||||
|
||||
|
||||
_dns_cache_cname_packet(context);
|
||||
|
||||
return 0;
|
||||
@@ -1174,7 +1208,7 @@ static int _dns_request_post(struct dns_server_post_context *context)
|
||||
struct dns_request *request = context->request;
|
||||
int ret = 0;
|
||||
|
||||
tlog(TLOG_DEBUG, "reply %s %d %d", request->domain, request->qtype, context->qtype);
|
||||
tlog(TLOG_DEBUG, "reply %s qtype: %d, rcode: %d", request->domain, request->qtype, context->packet->head.rcode);
|
||||
|
||||
if (request->conn == NULL) {
|
||||
context->do_reply = 0;
|
||||
@@ -1350,6 +1384,7 @@ static int dns_server_update_reply_packet_id(struct dns_request *request, unsign
|
||||
}
|
||||
|
||||
static void _dns_server_request_release(struct dns_request *request);
|
||||
static void _dns_server_request_release_complete(struct dns_request *request, int do_complete);
|
||||
|
||||
int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_server_post_context *context)
|
||||
{
|
||||
@@ -1380,13 +1415,14 @@ int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_s
|
||||
if (atomic_inc_return(&req->notified) != 1) {
|
||||
return 0;
|
||||
}
|
||||
req->rcode = request->rcode;
|
||||
/* When passthrough, modify the id to be the id of the client request. */
|
||||
dns_server_update_reply_packet_id(req, context->inpacket, context->inpacket_len);
|
||||
ret = _dns_reply_inpacket(req, context->inpacket, context->inpacket_len);
|
||||
}
|
||||
|
||||
req->request_pending_list = NULL;
|
||||
_dns_server_request_release(req);
|
||||
_dns_server_request_release_complete(req, 0);
|
||||
}
|
||||
pthread_mutex_unlock(&pending_list->request_list_lock);
|
||||
|
||||
@@ -1400,6 +1436,10 @@ static int _dns_server_request_complete(struct dns_request *request)
|
||||
int force_A = 0;
|
||||
int ttl = DNS_SERVER_TMOUT_TTL;
|
||||
|
||||
if (request->rcode == DNS_RC_SERVFAIL || request->rcode == DNS_RC_NXDOMAIN) {
|
||||
ttl = DNS_SERVER_FAIL_TTL;
|
||||
}
|
||||
|
||||
if (request->prefetch == 1) {
|
||||
return 0;
|
||||
}
|
||||
@@ -2312,9 +2352,9 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
|
||||
static int _dns_server_passthrough_rule_check(struct dns_request *request, char *domain, struct dns_packet *packet,
|
||||
unsigned int result_flag, int *pttl)
|
||||
{
|
||||
int ttl;
|
||||
int ttl = 0;
|
||||
char name[DNS_MAX_CNAME_LEN] = {0};
|
||||
int rr_count;
|
||||
int rr_count = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
struct dns_rrs *rrs = NULL;
|
||||
@@ -3724,7 +3764,8 @@ static int _dns_server_do_query(struct dns_request *request)
|
||||
// Get reference for AAAA query
|
||||
_dns_server_request_get(request);
|
||||
request->request_wait++;
|
||||
if (dns_client_query(request->domain, DNS_T_A, dns_server_resolve_callback, request, group_name, &options) != 0) {
|
||||
if (dns_client_query(request->domain, DNS_T_A, dns_server_resolve_callback, request, group_name, &options) !=
|
||||
0) {
|
||||
request->request_wait--;
|
||||
_dns_server_request_release(request);
|
||||
}
|
||||
@@ -3733,7 +3774,8 @@ static int _dns_server_do_query(struct dns_request *request)
|
||||
// Get reference for DNS query
|
||||
request->request_wait++;
|
||||
_dns_server_request_get(request);
|
||||
if (dns_client_query(request->domain, request->qtype, dns_server_resolve_callback, request, group_name, &options) != 0) {
|
||||
if (dns_client_query(request->domain, request->qtype, dns_server_resolve_callback, request, group_name, &options) !=
|
||||
0) {
|
||||
request->request_wait--;
|
||||
_dns_server_request_release(request);
|
||||
tlog(TLOG_ERROR, "send dns request failed.");
|
||||
@@ -3748,7 +3790,7 @@ errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _dns_server_parser_request(struct dns_request *request, struct dns_packet *packet)
|
||||
static int _dns_server_parser_request(struct dns_request *request, struct dns_packet *packet)
|
||||
{
|
||||
struct dns_rrs *rrs;
|
||||
int rr_count = 0;
|
||||
@@ -3780,7 +3822,6 @@ static int _dns_server_parser_request(struct dns_request *request, struct dns_pa
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* get request opts */
|
||||
rr_count = 0;
|
||||
rrs = dns_get_rrs_start(packet, DNS_RRS_OPT, &rr_count);
|
||||
@@ -3813,7 +3854,6 @@ static int _dns_server_recv(struct dns_server_conn_head *conn, unsigned char *in
|
||||
struct dns_packet *packet = (struct dns_packet *)packet_buff;
|
||||
struct dns_request *request = NULL;
|
||||
|
||||
|
||||
/* decode packet */
|
||||
tlog(TLOG_DEBUG, "recv query packet from %s, len = %d",
|
||||
gethost_by_addr(name, sizeof(name), (struct sockaddr *)from), inpacket_len);
|
||||
@@ -3861,7 +3901,7 @@ errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _dns_server_prefetch_setup_options(struct dns_request *request, struct dns_query_options *options)
|
||||
static int _dns_server_prefetch_setup_options(struct dns_request *request, struct dns_query_options *options)
|
||||
{
|
||||
if (options == NULL) {
|
||||
return 0;
|
||||
@@ -3875,7 +3915,8 @@ static int _dns_server_prefetch_setup_options(struct dns_request *request, struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_prefetch_request(char *domain, dns_type_t qtype, uint32_t server_flags,
|
||||
struct dns_query_options *options)
|
||||
{
|
||||
int ret = -1;
|
||||
struct dns_request *request = NULL;
|
||||
|
||||
Reference in New Issue
Block a user