test: add test case for ptr, suppress log.

This commit is contained in:
Nick Peng
2023-04-04 23:58:42 +08:00
parent fbdcb7ba41
commit d4e1da9955
8 changed files with 227 additions and 53 deletions

View File

@@ -21,7 +21,7 @@ OBJS=smartdns.o fast_ping.o dns_client.o dns_server.o dns.o util.o tlog.o dns_co
# cflags
ifndef CFLAGS
ifdef DEBUG
CFLAGS = -g
CFLAGS = -g -DDEBUG
else
CFLAGS = -O2
endif

View File

@@ -849,7 +849,7 @@ int dns_get_A(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned
return _dns_get_RAW(rrs, domain, maxsize, ttl, addr, &len);
}
int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, char *cname)
int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, const char *cname)
{
int rr_len = strnlen(cname, DNS_MAX_CNAME_LEN) + 1;
return _dns_add_RAW(packet, type, DNS_T_PTR, domain, ttl, cname, rr_len);
@@ -1862,7 +1862,7 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
while (context->ptr - start < rr_len) {
if (_dns_left_len(context) < 4) {
tlog(TLOG_WARN, "data length is invalid, %d:%d", _dns_left_len(context),
tlog(TLOG_DEBUG, "data length is invalid, %d:%d", _dns_left_len(context),
(int)(context->ptr - context->data));
return -1;
}
@@ -1870,7 +1870,7 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
opt_len = _dns_read_short(&context->ptr);
if (_dns_left_len(context) < opt_len) {
tlog(TLOG_ERROR, "read opt data failed, opt_code = %d, opt_len = %d", opt_code, opt_len);
tlog(TLOG_DEBUG, "read opt data failed, opt_code = %d, opt_len = %d", opt_code, opt_len);
return -1;
}

View File

@@ -257,7 +257,7 @@ int dns_add_A(struct dns_packet *packet, dns_rr_type type, const char *domain, i
unsigned char addr[DNS_RR_A_LEN]);
int dns_get_A(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[DNS_RR_A_LEN]);
int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, char *cname);
int dns_add_PTR(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, const char *cname);
int dns_get_PTR(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, char *cname, int cname_size);
int dns_add_AAAA(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl,

View File

@@ -1814,7 +1814,7 @@ static int _dns_client_create_socket_udp(struct dns_server_info *server_info)
if (connect(fd, &server_info->addr, server_info->ai_addrlen) != 0) {
if (errno == ENETUNREACH || errno == EHOSTUNREACH || errno == ECONNREFUSED) {
tlog(TLOG_WARN, "connect %s failed, %s", server_info->ip, strerror(errno));
tlog(TLOG_INFO, "connect %s failed, %s", server_info->ip, strerror(errno));
goto errout;
}
@@ -3375,6 +3375,7 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
if (server_info->fd <= 0) {
ret = _dns_client_create_socket(server_info);
if (ret != 0) {
server_info->prohibit = 1;
continue;
}
}

View File

@@ -161,50 +161,3 @@ cache-persist no)""");
EXPECT_EQ(client.GetAnswer()[0].GetType(), "AAAA");
EXPECT_EQ(client.GetAnswer()[0].GetData(), "64:ff9b::1010:1010");
}
TEST_F(Address, ptr)
{
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) {
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 700);
return smartdns::SERVER_REQUEST_OK;
} else if (request->qtype == DNS_T_AAAA) {
smartdns::MockServer::AddIP(request, request->domain.c_str(), "64:ff9b::102:304", 700);
return smartdns::SERVER_REQUEST_OK;
}
return smartdns::SERVER_REQUEST_SOA;
});
server.Start(R"""(bind [::]:60053
server 127.0.0.1:61053
log-num 0
log-console yes
log-level debug
speed-check-mode none
expand-ptr-from-address yes
address /a.com/10.11.12.13
address /a.com/64:ff9b::1010:1010
cache-persist no)""");
smartdns::Client client;
ASSERT_TRUE(client.Query("13.12.11.10.in-addr.arpa PTR", 60053));
std::cout << client.GetResult() << std::endl;
ASSERT_EQ(client.GetAnswerNum(), 1);
EXPECT_EQ(client.GetStatus(), "NOERROR");
EXPECT_EQ(client.GetAnswer()[0].GetName(), "13.12.11.10.in-addr.arpa");
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
EXPECT_EQ(client.GetAnswer()[0].GetType(), "PTR");
EXPECT_EQ(client.GetAnswer()[0].GetData(), "a.com.");
ASSERT_TRUE(client.Query("0.1.0.1.0.1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa PTR", 60053));
std::cout << client.GetResult() << std::endl;
ASSERT_EQ(client.GetAnswerNum(), 1);
EXPECT_EQ(client.GetStatus(), "NOERROR");
EXPECT_EQ(client.GetAnswer()[0].GetName(),
"0.1.0.1.0.1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa");
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
EXPECT_EQ(client.GetAnswer()[0].GetType(), "PTR");
EXPECT_EQ(client.GetAnswer()[0].GetData(), "a.com.");
}

View File

@@ -20,6 +20,11 @@
#include "include/utils.h"
#include "server.h"
#include "gtest/gtest.h"
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <openssl/rand.h>
#include <sys/socket.h>
TEST(Bind, tls)
{
@@ -192,3 +197,58 @@ cache-persist no)""");
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
}
TEST(Bind, malformed_packet)
{
smartdns::MockServer server_upstream;
smartdns::Server server;
server_upstream.Start("udp://0.0.0.0:62053", [](struct smartdns::ServerRequestContext *request) {
if (request->qtype == DNS_T_A) {
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
return smartdns::SERVER_REQUEST_OK;
}
return smartdns::SERVER_REQUEST_SOA;
});
server.Start(R"""(
bind [::]:60053@lo
server 127.0.0.1:62053
log-num 0
log-console yes
log-level info
cache-persist no)""");
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
ASSERT_NE(sockfd, -1);
Defer
{
close(sockfd);
};
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(60053);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
for (int i = 0; i < 100000; i++) {
char buf[4096];
int len = random() % 4096;
if (len <= 0) {
len = 1;
}
RAND_bytes((unsigned char *)buf, len);
sendto(sockfd, buf, len, 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
}
smartdns::Client client;
ASSERT_TRUE(client.Query("a.com", 60053));
std::cout << client.GetResult() << std::endl;
ASSERT_EQ(client.GetAnswerNum(), 1);
EXPECT_EQ(client.GetStatus(), "NOERROR");
EXPECT_LT(client.GetQueryTime(), 100);
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
}

156
test/cases/test-ptr.cc Normal file
View File

@@ -0,0 +1,156 @@
/*************************************************************************
*
* Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "client.h"
#include "dns.h"
#include "include/utils.h"
#include "server.h"
#include "util.h"
#include "gtest/gtest.h"
#include <fstream>
class Ptr : public ::testing::Test
{
protected:
virtual void SetUp() {}
virtual void TearDown() {}
};
TEST_F(Ptr, query)
{
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) {
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
return smartdns::SERVER_REQUEST_OK;
}
if (request->qtype == DNS_T_PTR) {
dns_add_PTR(request->response_packet, DNS_RRS_AN, request->domain.c_str(), 30, "my-hostname");
request->response_packet->head.rcode = DNS_RC_NOERROR;
return smartdns::SERVER_REQUEST_OK;
}
return smartdns::SERVER_REQUEST_SOA;
});
server.Start(R"""(bind [::]:60053
server 127.0.0.1:61053
log-num 0
log-console yes
dualstack-ip-selection no
log-level debug
cache-persist no)""");
smartdns::Client client;
ASSERT_TRUE(client.Query("4.3.2.1.in-addr.arpa PTR", 60053));
std::cout << client.GetResult() << std::endl;
ASSERT_EQ(client.GetAnswerNum(), 1);
EXPECT_EQ(client.GetStatus(), "NOERROR");
EXPECT_EQ(client.GetAnswer()[0].GetName(), "4.3.2.1.in-addr.arpa");
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
EXPECT_EQ(client.GetAnswer()[0].GetType(), "PTR");
EXPECT_EQ(client.GetAnswer()[0].GetData(), "my-hostname.");
}
TEST_F(Ptr, address_expand_ptr)
{
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) {
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 700);
return smartdns::SERVER_REQUEST_OK;
} else if (request->qtype == DNS_T_AAAA) {
smartdns::MockServer::AddIP(request, request->domain.c_str(), "64:ff9b::102:304", 700);
return smartdns::SERVER_REQUEST_OK;
}
return smartdns::SERVER_REQUEST_SOA;
});
server.Start(R"""(bind [::]:60053
server 127.0.0.1:61053
log-num 0
log-console yes
log-level debug
speed-check-mode none
expand-ptr-from-address yes
address /a.com/10.11.12.13
address /a.com/64:ff9b::1010:1010
cache-persist no)""");
smartdns::Client client;
ASSERT_TRUE(client.Query("13.12.11.10.in-addr.arpa PTR", 60053));
std::cout << client.GetResult() << std::endl;
ASSERT_EQ(client.GetAnswerNum(), 1);
EXPECT_EQ(client.GetStatus(), "NOERROR");
EXPECT_EQ(client.GetAnswer()[0].GetName(), "13.12.11.10.in-addr.arpa");
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
EXPECT_EQ(client.GetAnswer()[0].GetType(), "PTR");
EXPECT_EQ(client.GetAnswer()[0].GetData(), "a.com.");
ASSERT_TRUE(client.Query("0.1.0.1.0.1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa PTR", 60053));
std::cout << client.GetResult() << std::endl;
ASSERT_EQ(client.GetAnswerNum(), 1);
EXPECT_EQ(client.GetStatus(), "NOERROR");
EXPECT_EQ(client.GetAnswer()[0].GetName(),
"0.1.0.1.0.1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa");
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
EXPECT_EQ(client.GetAnswer()[0].GetType(), "PTR");
EXPECT_EQ(client.GetAnswer()[0].GetData(), "a.com.");
}
TEST_F(Ptr, smartdns)
{
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) {
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
return smartdns::SERVER_REQUEST_OK;
}
if (request->qtype == DNS_T_PTR) {
dns_add_PTR(request->response_packet, DNS_RRS_AN, request->domain.c_str(), 30, "my-hostname");
request->response_packet->head.rcode = DNS_RC_NOERROR;
return smartdns::SERVER_REQUEST_OK;
}
return smartdns::SERVER_REQUEST_SOA;
});
server.Start(R"""(bind [::]:60053
server 127.0.0.1:61053
server-name my-server
log-num 0
log-console yes
dualstack-ip-selection no
log-level debug
cache-persist no)""");
smartdns::Client client;
ASSERT_TRUE(client.Query("1.0.0.127.in-addr.arpa PTR", 60053));
std::cout << client.GetResult() << std::endl;
ASSERT_EQ(client.GetAnswerNum(), 1);
EXPECT_EQ(client.GetStatus(), "NOERROR");
EXPECT_EQ(client.GetAnswer()[0].GetName(), "1.0.0.127.in-addr.arpa");
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
EXPECT_EQ(client.GetAnswer()[0].GetType(), "PTR");
EXPECT_EQ(client.GetAnswer()[0].GetData(), "my-server.");
}

View File

@@ -243,6 +243,7 @@ bool MockServer::Start(const std::string &url, ServerRequest callback)
int port;
char c_path[256];
int fd;
int yes = 1;
struct sockaddr_storage addr;
socklen_t addrlen;
@@ -271,6 +272,9 @@ bool MockServer::Start(const std::string &url, ServerRequest callback)
return false;
}
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes));
if (bind(fd, (struct sockaddr *)&addr, addrlen) != 0) {
close(fd);
return false;