From eb0d0336de5d00459b33f59957fde91132120c03 Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Tue, 14 Nov 2023 22:55:39 +0800 Subject: [PATCH] dns_server: fix issue of incorrect caching results when enable ip white list. --- src/dns_server.c | 27 ++++++++++++++---------- test/cases/test-ip-rule.cc | 42 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/dns_server.c b/src/dns_server.c index f21c3cc..b9ddfb9 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -3214,6 +3214,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d int j = 0; struct dns_rrs *rrs = NULL; int ret = 0; + int is_skip = 0; if (packet->head.rcode != DNS_RC_NOERROR && packet->head.rcode != DNS_RC_NXDOMAIN) { if (request->rcode == DNS_RC_SERVFAIL) { @@ -3225,11 +3226,6 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d return -1; } - request->remote_server_fail = 0; - if (request->rcode == DNS_RC_SERVFAIL) { - request->rcode = packet->head.rcode; - } - for (j = 1; j < DNS_RRS_OPT; j++) { rrs = dns_get_rrs_start(packet, j, &rr_count); for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) { @@ -3239,6 +3235,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d if (ret == -1) { break; } else if (ret == -2) { + is_skip = 1; continue; } else if (ret == -3) { return -1; @@ -3250,6 +3247,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d if (ret == -1) { break; } else if (ret == -2) { + is_skip = 1; continue; } else if (ret == -3) { return -1; @@ -3304,6 +3302,11 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d } } + request->remote_server_fail = 0; + if (request->rcode == DNS_RC_SERVFAIL && is_skip == 0) { + request->rcode = packet->head.rcode; + } + return 0; } @@ -3329,11 +3332,6 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, const return 0; } - request->remote_server_fail = 0; - if (request->rcode == DNS_RC_SERVFAIL) { - request->rcode = packet->head.rcode; - } - for (j = 1; j < DNS_RRS_OPT; j++) { rrs = dns_get_rrs_start(packet, j, &rr_count); for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) { @@ -3438,6 +3436,11 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, const } } + request->remote_server_fail = 0; + if (request->rcode == DNS_RC_SERVFAIL) { + request->rcode = packet->head.rcode; + } + *pttl = ttl; return -1; } @@ -7063,6 +7066,8 @@ static int _dns_create_socket(const char *host_ip, int type) tlog(TLOG_ERROR, "set socket opt failed."); goto errout; } + /* enable TCP_FASTOPEN */ + setsockopt(fd, SOL_TCP, TCP_FASTOPEN, &optval, sizeof(optval)); setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)); } else { setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &optval, sizeof(optval)); @@ -7261,7 +7266,7 @@ static int _dns_server_socket_tls(struct dns_bind_ip *bind_ip, DNS_CONN_TYPE con } SSL_CTX_set_session_cache_mode(ssl_ctx, - SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL | SSL_SESS_CACHE_NO_AUTO_CLEAR); + SSL_SESS_CACHE_BOTH | SSL_SESS_CACHE_NO_INTERNAL | SSL_SESS_CACHE_NO_AUTO_CLEAR); SSL_CTX_set_default_passwd_cb(ssl_ctx, _dns_server_socket_tls_ssl_pass_callback); SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, bind_ip); diff --git a/test/cases/test-ip-rule.cc b/test/cases/test-ip-rule.cc index 550b7f0..7533255 100644 --- a/test/cases/test-ip-rule.cc +++ b/test/cases/test-ip-rule.cc @@ -73,6 +73,48 @@ cache-persist no)"""); EXPECT_EQ(client.GetAnswer()[0].GetData(), "4.5.6.7"); } +TEST_F(IPRule, white_list_not_in) +{ + smartdns::MockServer server_upstream; + smartdns::MockServer server_upstream2; + smartdns::Server server; + + server_upstream.Start("udp://0.0.0.0:61053", [](struct smartdns::ServerRequestContext *request) { + if (request->qtype != DNS_T_A) { + return smartdns::SERVER_REQUEST_SOA; + } + + smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 611); + return smartdns::SERVER_REQUEST_OK; + }); + + server_upstream2.Start("udp://0.0.0.0:62053", [](struct smartdns::ServerRequestContext *request) { + if (request->qtype != DNS_T_A) { + return smartdns::SERVER_REQUEST_SOA; + } + + smartdns::MockServer::AddIP(request, request->domain.c_str(), "9.10.11.12", 611); + return smartdns::SERVER_REQUEST_OK; + }); + + /* this ip will be discard, but is reachable */ + server.MockPing(PING_TYPE_ICMP, "1.2.3.4", 60, 10); + + server.Start(R"""(bind [::]:60053 +server udp://127.0.0.1:61053 -whitelist-ip +server udp://127.0.0.1:62053 -whitelist-ip +whitelist-ip 4.5.6.7/24 +log-num 0 +log-console yes +log-level debug +cache-persist no)"""); + smartdns::Client client; + ASSERT_TRUE(client.Query("a.com", 60053)); + std::cout << client.GetResult() << std::endl; + ASSERT_EQ(client.GetAnswerNum(), 0); + EXPECT_EQ(client.GetStatus(), "SERVFAIL"); +} + TEST_F(IPRule, black_list) { smartdns::MockServer server_upstream;