Browse Source

ipv6: fix ipv4 in ipv6 address issue.

Nick Peng 3 months ago
parent
commit
8bae7c110a
5 changed files with 76 additions and 10 deletions
  1. 1 4
      src/dns_conf/address.c
  2. 1 1
      src/dns_server/speed_check.c
  3. 38 0
      test/cases/test-address.cc
  4. 36 0
      test/cases/test-dns64.cc
  5. 0 5
      test/server.cc

+ 1 - 4
src/dns_conf/address.c

@@ -124,10 +124,7 @@ int _conf_domain_rule_address(char *domain, const char *domain_address)
 		case AF_INET6: {
 		case AF_INET6: {
 			struct sockaddr_in6 *addr_in6 = NULL;
 			struct sockaddr_in6 *addr_in6 = NULL;
 			addr_in6 = (struct sockaddr_in6 *)&addr;
 			addr_in6 = (struct sockaddr_in6 *)&addr;
-			if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr) && ipv4_num < DNS_MAX_REPLY_IP_NUM) {
-				memcpy(ipv4_addr[ipv4_num], addr_in6->sin6_addr.s6_addr + 12, DNS_RR_A_LEN);
-				ipv4_num++;
-			} else if (ipv6_num < DNS_MAX_REPLY_IP_NUM) {
+			if (ipv6_num < DNS_MAX_REPLY_IP_NUM) {
 				memcpy(ipv6_addr[ipv6_num], addr_in6->sin6_addr.s6_addr, DNS_RR_AAAA_LEN);
 				memcpy(ipv6_addr[ipv6_num], addr_in6->sin6_addr.s6_addr, DNS_RR_AAAA_LEN);
 				ipv6_num++;
 				ipv6_num++;
 			}
 			}

+ 1 - 1
src/dns_server/speed_check.c

@@ -120,7 +120,7 @@ static void _dns_server_ping_result(struct ping_host_struct *ping_host, const ch
 				request->ping_time = rtt;
 				request->ping_time = rtt;
 				request->has_cname = 0;
 				request->has_cname = 0;
 				request->has_ip = 1;
 				request->has_ip = 1;
-				memcpy(request->ip_addr, addr_in6->sin6_addr.s6_addr + 12, 4);
+				memcpy(request->ip_addr, addr_in6->sin6_addr.s6_addr, 16);
 				request->ip_addr_type = DNS_T_A;
 				request->ip_addr_type = DNS_T_A;
 				if (addr_map && addr_map->cname[0] != 0) {
 				if (addr_map && addr_map->cname[0] != 0) {
 					request->has_cname = 1;
 					request->has_cname = 1;

+ 38 - 0
test/cases/test-address.cc

@@ -480,3 +480,41 @@ address /com/#
 	ASSERT_EQ(client.GetAnswerNum(), 0);
 	ASSERT_EQ(client.GetAnswerNum(), 0);
 	EXPECT_EQ(client.GetStatus(), "NXDOMAIN");
 	EXPECT_EQ(client.GetStatus(), "NXDOMAIN");
 }
 }
+
+
+TEST_F(Address, ipv4_in_Test)
+{
+	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
+speed-check-mode none
+address /a.com/::ffff:192.168.1.1
+)""");
+	smartdns::Client client;
+	ASSERT_TRUE(client.Query("a.com AAAA", 60053));
+	std::cout << client.GetResult() << std::endl;
+	ASSERT_EQ(client.GetAnswerNum(), 1);
+	EXPECT_EQ(client.GetStatus(), "NOERROR");
+	EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
+	EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
+	EXPECT_EQ(client.GetAnswer()[0].GetType(), "AAAA");
+	EXPECT_EQ(client.GetAnswer()[0].GetData(), "::ffff:192.168.1.1");
+
+	ASSERT_TRUE(client.Query("a.com A", 60053));
+	std::cout << client.GetResult() << std::endl;
+	ASSERT_EQ(client.GetAnswerNum(), 0);
+	EXPECT_EQ(client.GetStatus(), "NOERROR");
+}

+ 36 - 0
test/cases/test-dns64.cc

@@ -141,3 +141,39 @@ dns64 64:ff9b::/96
 	EXPECT_EQ(client.GetAnswer()[0].GetData(), "2001:db8::1");
 	EXPECT_EQ(client.GetAnswer()[0].GetData(), "2001:db8::1");
 }
 }
 
 
+
+TEST_F(DNS64, ipv4_in_ipv6)
+{
+	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;
+		} 
+
+		if (request->qtype == DNS_T_AAAA) {
+			smartdns::MockServer::AddIP(request, request->domain.c_str(), "::ffff:1.2.3.4");
+			smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::1");
+			return smartdns::SERVER_REQUEST_OK;
+		}
+		return smartdns::SERVER_REQUEST_SOA;
+	});
+
+	server.MockPing(PING_TYPE_ICMP, "::ffff:1.2.3.4", 60, 10);
+	server.MockPing(PING_TYPE_ICMP, "2001:db8::1", 60, 90);
+
+	server.Start(R"""(bind [::]:60053
+server 127.0.0.1:61053
+)""");
+	smartdns::Client client;
+	ASSERT_TRUE(client.Query("a.com AAAA", 60053));
+	std::cout << client.GetResult() << std::endl;
+	ASSERT_EQ(client.GetAnswerNum(), 1);
+	EXPECT_EQ(client.GetStatus(), "NOERROR");
+	EXPECT_LT(client.GetQueryTime(), 1200);
+	EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
+	EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
+	EXPECT_EQ(client.GetAnswer()[0].GetData(), "::ffff:1.2.3.4");
+}
+

+ 0 - 5
test/server.cc

@@ -199,11 +199,6 @@ bool MockServer::AddIP(struct ServerRequestContext *request, const std::string &
 					  (unsigned char *)&addr4->sin_addr.s_addr);
 					  (unsigned char *)&addr4->sin_addr.s_addr);
 		} else if (addr.ss_family == AF_INET6) {
 		} else if (addr.ss_family == AF_INET6) {
 			struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
 			struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
-			if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
-				dns_add_A(request->response_packet, DNS_RRS_AN, domain.c_str(), ttl,
-						  (unsigned char *)&addr6->sin6_addr.s6_addr[12]);
-				return true;
-			}
 			dns_add_AAAA(request->response_packet, DNS_RRS_AN, domain.c_str(), ttl,
 			dns_add_AAAA(request->response_packet, DNS_RRS_AN, domain.c_str(), ttl,
 						 (unsigned char *)&addr6->sin6_addr.s6_addr);
 						 (unsigned char *)&addr6->sin6_addr.s6_addr);
 		}
 		}