From f68e4eda1c3e0bfb8cd23b3a68d71dee9b82242e Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Thu, 11 Oct 2018 23:57:42 +0800 Subject: [PATCH] Add force AAAA SOA feature --- ReadMe.md | 1 + ReadMe_zh-CN.md | 1 + src/conf.c | 14 ++++++++++++++ src/conf.h | 1 + src/dns_server.c | 29 ++++++++++++++++++++++++++++- 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 65c419d..4017fa3 100755 --- a/ReadMe.md +++ b/ReadMe.md @@ -382,6 +382,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use |server-tcp|Upstream TCP DNS server|None|[IP][:port], Repeatable| server-tcp 8.8.8.8:53 |address|Domain IP address|None|address /domain/ip| address /www.example.com/1.2.3.4 |bogus-nxdomain|bogus IP address|None|[IP],Repeatable| bogus-nxdomain 1.2.3.4 +|force-AAAA-SOA|force AAAA query return SOA|no|[yes\|no]|force-AAAA-SOA yes ## [Donate](#Donate) diff --git a/ReadMe_zh-CN.md b/ReadMe_zh-CN.md index e6333dd..7d1b922 100644 --- a/ReadMe_zh-CN.md +++ b/ReadMe_zh-CN.md @@ -382,6 +382,7 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms |server-tcp|上游TCP DNS|无|[IP][:port],可重复| server-tcp 8.8.8.8:53 |address|指定域名IP地址|无|address /domain/ip| address /www.example.com/1.2.3.4 |bogus-nxdomain|假冒IP地址过滤|无|[ip],可重复| bogus-nxdomain 1.2.3.4 +|force-AAAA-SOA|强制AAAA地址返回SOA|no|[yes\|no]|force-AAAA-SOA yes ## [Donate](#Donate) diff --git a/src/conf.c b/src/conf.c index ffbbaf5..1b046e6 100644 --- a/src/conf.c +++ b/src/conf.c @@ -29,6 +29,7 @@ art_tree dns_conf_address; int dns_conf_rr_ttl; int dns_conf_rr_ttl_min; int dns_conf_rr_ttl_max; +int dns_conf_force_AAAA_SOA; int load_conf_file(const char *file); @@ -224,6 +225,18 @@ int config_cache_prefetch_domain(char *value) return 0; } +int config_force_AAAA_SOA(char *value) +{ + /* read dns cache size */ + if (strncmp("yes", value, sizeof("yes")) == 0 || strncmp("YES", value, sizeof("YES")) == 0) { + dns_conf_force_AAAA_SOA = 1; + } else if (strncmp("no", value, sizeof("no")) == 0 || strncmp("NO", value, sizeof("NO")) == 0) { + dns_conf_force_AAAA_SOA = 0; + } + + return 0; +} + int config_log_level(char *value) { /* read log level and set */ @@ -467,6 +480,7 @@ struct config_item config_item[] = { {"rr-ttl", config_rr_ttl}, {"rr-ttl-min", config_rr_ttl_min}, {"rr-ttl-max", config_rr_ttl_max}, + {"force-AAAA-SOA", config_force_AAAA_SOA}, {"bogus-nxdomain", conf_bogus_nxdomain}, {"conf-file", config_addtional_file}, }; diff --git a/src/conf.h b/src/conf.h index 0f1afdf..cf33117 100644 --- a/src/conf.h +++ b/src/conf.h @@ -63,6 +63,7 @@ extern art_tree dns_conf_address; extern int dns_conf_rr_ttl; extern int dns_conf_rr_ttl_min; extern int dns_conf_rr_ttl_max; +extern int dns_conf_force_AAAA_SOA; int dns_bogus_nxdomain_exists(unsigned char *ip, dns_type_t addr_type); diff --git a/src/dns_server.c b/src/dns_server.c index 9ec9e2f..4f5b1db 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -541,10 +541,11 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain, int j = 0; struct dns_rrs *rrs = NULL; - if (packet->head.rcode != DNS_RC_NOERROR) { + if (packet->head.rcode != DNS_RC_NOERROR && packet->head.rcode != DNS_RC_NXDOMAIN) { if (request->rcode == DNS_RC_SERVFAIL) { request->rcode = packet->head.rcode; } + tlog(TLOG_DEBUG, "inquery failed, %s, rcode = %d, id = %d\n", domain, packet->head.rcode, packet->head.id); return -1; } @@ -793,6 +794,27 @@ errout: return -1; } +static int _dns_server_reply_SOA(int rcode, struct dns_request *request, struct dns_packet *packet) +{ + struct dns_soa *soa; + + request->rcode = rcode; + request->has_soa = 1; + + soa = &request->soa; + + strcpy(soa->mname, "a.gtld-servers.net"); + strcpy(soa->rname, "nstld.verisign-grs.com"); + soa->serial = 1800; + soa->refresh = 1800; + soa->retry = 900; + soa->expire = 604800; + soa->minimum = 86400; + _dns_reply(request); + + return 0; +} + static void _dns_server_log_rule(char *domain, unsigned char *rule_key, int rule_key_len) { char rule_name[DNS_MAX_CNAME_LEN]; @@ -997,6 +1019,11 @@ static int _dns_server_recv(unsigned char *inpacket, int inpacket_len, struct so case DNS_T_A: break; case DNS_T_AAAA: + if (dns_conf_force_AAAA_SOA == 1) { + _dns_server_reply_SOA(DNS_RC_NOERROR, request, packet); + free(request); + return 0; + } break; default: tlog(TLOG_DEBUG, "unsupport qtype: %d, domain: %s", qtype, request->domain);