diff --git a/src/dns_client.c b/src/dns_client.c index d0f7eb9..b5d9436 100644 --- a/src/dns_client.c +++ b/src/dns_client.c @@ -3444,7 +3444,7 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet, } int num = atomic_dec_return(&query->dns_request_sent); - if (num == 0) { + if (num == 0 && send_count > 0) { _dns_client_query_remove(query); } diff --git a/test/cases/test-server.cc b/test/cases/test-server.cc new file mode 100644 index 0000000..dffcc0a --- /dev/null +++ b/test/cases/test-server.cc @@ -0,0 +1,68 @@ +/************************************************************************* + * + * Copyright (C) 2018-2023 Ruilin Peng (Nick) . + * + * smartdns is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * smartdns is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "client.h" +#include "dns.h" +#include "include/utils.h" +#include "server.h" +#include "gtest/gtest.h" + +class Server : public ::testing::Test +{ + protected: + virtual void SetUp() {} + virtual void TearDown() {} +}; + +TEST_F(Server, all_unreach) +{ + smartdns::MockServer server_upstream; + 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); + EXPECT_EQ(request->domain, "e.com"); + return smartdns::SERVER_REQUEST_OK; + }); + + server.MockPing(PING_TYPE_ICMP, "2001::", 128, 10000); + server.Start(R"""(bind [::]:60053 +bind-tcp [::]:60053 +server tls://255.255.255.255 +server https://255.255.255.255 +server tcp://255.255.255.255 +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; + EXPECT_EQ(client.GetStatus(), "SERVFAIL"); + EXPECT_EQ(client.GetAnswerNum(), 0); + + /* server should not crash */ + ASSERT_TRUE(client.Query("a.com +tcp", 60053)); + std::cout << client.GetResult() << std::endl; + EXPECT_EQ(client.GetStatus(), "SERVFAIL"); + EXPECT_EQ(client.GetAnswerNum(), 0); +}