From 14330dd5daf1f42e0b1ea3c1544d12f8981bc840 Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Fri, 3 Nov 2023 23:48:34 +0800 Subject: [PATCH] dns_server: cache ptr record --- src/dns_server.c | 150 +++++++++++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 52 deletions(-) diff --git a/src/dns_server.c b/src/dns_server.c index 128441b7a5..80d7290933 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -953,7 +953,7 @@ static int _dns_add_rrs(struct dns_server_post_context *context) char *domain = request->domain; if (request->has_ptr) { /* add PTR record */ - ret = dns_add_PTR(context->packet, DNS_RRS_AN, request->domain, 30, request->ptr_hostname); + ret = dns_add_PTR(context->packet, DNS_RRS_AN, request->domain, request->ip_ttl, request->ptr_hostname); } /* add CNAME record */ @@ -1258,6 +1258,22 @@ static inline int _dns_server_expired_cache_ttl(struct dns_cache *cache) return cache->info.insert_time + cache->info.ttl + dns_conf_serve_expired_ttl - time(NULL); } +static int _dns_cache_is_specify_packet(int qtype) +{ + switch (qtype) { + case DNS_T_PTR: + case DNS_T_HTTPS: + case DNS_T_TXT: + case DNS_T_SRV: + break; + default: + return -1; + break; + } + + return 0; +} + static int _dns_server_get_cache_timeout(struct dns_request *request, struct dns_cache_key *cache_key, int ttl) { int timeout = 0; @@ -1266,7 +1282,7 @@ static int _dns_server_get_cache_timeout(struct dns_request *request, struct dns return ttl + 1; } - if (dns_conf_prefetch) { + if (dns_conf_prefetch && _dns_cache_is_specify_packet(request->qtype) != 0) { if (dns_conf_serve_expired) { timeout = dns_conf_serve_expired_prefetch_time; if (timeout == 0) { @@ -1514,15 +1530,15 @@ static int _dns_cache_packet(struct dns_server_post_context *context) cache_key.query_flag = request->server_flags; if (request->prefetch) { - if (dns_cache_replace(&cache_key, request->rcode, context->reply_ttl, -1, - _dns_server_get_cache_timeout(request, &cache_key, context->reply_ttl), + if (dns_cache_replace(&cache_key, request->rcode, request->ip_ttl, -1, + _dns_server_get_cache_timeout(request, &cache_key, request->ip_ttl), !request->prefetch_expired_domain, cache_packet) != 0) { goto errout; } } else { /* insert result to cache */ - if (dns_cache_insert(&cache_key, request->rcode, context->reply_ttl, -1, - _dns_server_get_cache_timeout(request, NULL, context->reply_ttl), cache_packet) != 0) { + if (dns_cache_insert(&cache_key, request->rcode, request->ip_ttl, -1, + _dns_server_get_cache_timeout(request, NULL, request->ip_ttl), cache_packet) != 0) { goto errout; } } @@ -1585,15 +1601,8 @@ static int _dns_result_callback(struct dns_server_post_context *context) static int _dns_cache_specify_packet(struct dns_server_post_context *context) { - switch (context->qtype) { - case DNS_T_PTR: - case DNS_T_HTTPS: - case DNS_T_TXT: - case DNS_T_SRV: - break; - default: + if (_dns_cache_is_specify_packet(context->qtype) != 0) { return 0; - break; } return _dns_cache_packet(context); @@ -3969,6 +3978,50 @@ static int _dns_server_process_local_ptr(struct dns_request *request) return -1; } +static int _dns_server_get_local_ttl(struct dns_request *request) +{ + struct dns_ttl_rule *ttl_rule; + + /* get domain rule flag */ + ttl_rule = _dns_server_get_dns_rule(request, DOMAIN_RULE_TTL); + if (ttl_rule != NULL) { + if (ttl_rule->ttl > 0) { + return ttl_rule->ttl; + } + } + + if (dns_conf_local_ttl > 0) { + return dns_conf_local_ttl; + } + + if (dns_conf_rr_ttl > 0) { + return dns_conf_rr_ttl; + } + + if (dns_conf_rr_ttl_min > 0) { + return dns_conf_rr_ttl_min; + } + + return DNS_SERVER_ADDR_TTL; +} + +static int _dns_server_process_private_ptr(struct dns_request *request) +{ + int a, b, c, d; + int ret = sscanf(request->domain, "%d.%d.%d.%d.in-addr.arpa", &a, &b, &c, &d); + if (ret != 4) { + return -1; + } + + if (d == 10 || (d == 172 && c >= 16 && c <= 31) || (d == 192 && c == 168)) { + request->has_soa = 1; + _dns_server_setup_soa(request); + return 0; + } + + return -1; +} + static int _dns_server_process_ptr(struct dns_request *request) { if (_dns_server_process_ptrs(request) == 0) { @@ -3979,14 +4032,20 @@ static int _dns_server_process_ptr(struct dns_request *request) goto reply_exit; } + if (_dns_server_process_private_ptr(request) == 0) { + goto reply_exit; + } + return -1; reply_exit: request->rcode = DNS_RC_NOERROR; + request->ip_ttl = _dns_server_get_local_ttl(request); struct dns_server_post_context context; _dns_server_post_context_init(&context, request); context.do_reply = 1; context.do_audit = 0; + context.do_cache = 1; _dns_request_post(&context); return 0; } @@ -4275,33 +4334,6 @@ static int _dns_server_pre_process_rule_flags(struct dns_request *request) return 0; } -static int _dns_server_get_local_ttl(struct dns_request *request) -{ - struct dns_ttl_rule *ttl_rule; - - /* get domain rule flag */ - ttl_rule = _dns_server_get_dns_rule(request, DOMAIN_RULE_TTL); - if (ttl_rule != NULL) { - if (ttl_rule->ttl > 0) { - return ttl_rule->ttl; - } - } - - if (dns_conf_local_ttl > 0) { - return dns_conf_local_ttl; - } - - if (dns_conf_rr_ttl > 0) { - return dns_conf_rr_ttl; - } - - if (dns_conf_rr_ttl_min > 0) { - return dns_conf_rr_ttl_min; - } - - return DNS_SERVER_ADDR_TTL; -} - static int _dns_server_address_generate_order(int orders[], int order_num, int max_order_count) { int i = 0; @@ -4918,6 +4950,10 @@ static int _dns_server_process_cache(struct dns_request *request) goto reply_cache; } + if (request->qtype != DNS_T_A && request->qtype != DNS_T_AAAA) { + goto reply_cache; + } + if (request->dualstack_selection) { int dualstack_qtype = 0; if (request->qtype == DNS_T_A) { @@ -4925,7 +4961,7 @@ static int _dns_server_process_cache(struct dns_request *request) } else if (request->qtype == DNS_T_AAAA) { dualstack_qtype = DNS_T_A; } else { - goto out; + goto reply_cache; } cache_key.qtype = dualstack_qtype; @@ -5114,20 +5150,26 @@ static int _dns_server_process_smartdns_domain(struct dns_request *request) return _dns_server_reply_request_eth_ip(request); } +static int _dns_server_process_ptr_query(struct dns_request *request) +{ + if (request->qtype != DNS_T_PTR) { + return -1; + } + + if (_dns_server_process_ptr(request) == 0) { + return 0; + } + + request->passthrough = 1; + return -1; +} + static int _dns_server_process_special_query(struct dns_request *request) { int ret = 0; switch (request->qtype) { case DNS_T_PTR: - /* return PTR record */ - ret = _dns_server_process_ptr(request); - if (ret == 0) { - goto clean_exit; - } else { - /* pass to upstream server */ - request->passthrough = 1; - } break; case DNS_T_SVCB: ret = _dns_server_process_srv(request); @@ -5141,7 +5183,6 @@ static int _dns_server_process_special_query(struct dns_request *request) case DNS_T_A: break; case DNS_T_AAAA: - break; default: tlog(TLOG_DEBUG, "unsupported qtype: %d, domain: %s", request->qtype, request->domain); @@ -5400,6 +5441,11 @@ static int _dns_server_do_query(struct dns_request *request, int skip_notify_eve } } + /* process ptr */ + if (_dns_server_process_ptr_query(request) == 0) { + goto clean_exit; + } + ret = _dns_server_set_to_pending_list(request); if (ret == 0) { goto clean_exit; @@ -6467,7 +6513,7 @@ static int _dns_server_cache_expired(struct dns_cache *dns_cache) return -1; } - if (dns_conf_prefetch == 1) { + if (dns_conf_prefetch == 1 && _dns_cache_is_specify_packet(dns_cache->info.qtype) != 0) { if (dns_conf_serve_expired == 1) { return _dns_server_prefetch_expired_domain(dns_cache); } else {