Selaa lähdekoodia

domain-rule: Exceptions are allowed when enable force-AAAA-SOA

Nick Peng 2 vuotta sitten
vanhempi
sitoutus
fa5e519368
4 muutettua tiedostoa jossa 97 lisäystä ja 16 poistoa
  1. 2 0
      etc/smartdns/smartdns.conf
  2. 15 11
      src/dns_conf.c
  3. 5 4
      src/dns_server.c
  4. 75 1
      test/cases/test-qtype-soa.cc

+ 2 - 0
etc/smartdns/smartdns.conf

@@ -106,7 +106,9 @@ bind [::]:53
 
 # force specific qtype return soa
 # force-qtype-SOA [qtypeid |...]
+# force-qtype-SOA [qtypeid,...]
 # force-qtype-SOA 65 28
+# force-qtype-SOA 65,28
 force-qtype-SOA 65
 
 # Enable IPV4, IPV6 dual stack IP optimization selection strategy

+ 15 - 11
src/dns_conf.c

@@ -2227,19 +2227,23 @@ static int _config_qtype_soa(void *data, int argc, char *argv[])
 	}
 
 	for (i = 1; i < argc; i++) {
-		soa_list = malloc(sizeof(*soa_list));
-		if (soa_list == NULL) {
-			tlog(TLOG_ERROR, "cannot malloc memory");
-			return -1;
-		}
+		char sub_arg[1024];
+		safe_strncpy(sub_arg, argv[i], sizeof(sub_arg));
+		for (char *tok = strtok(sub_arg, ","); tok; tok = strtok(NULL, ",")) {
+			soa_list = malloc(sizeof(*soa_list));
+			if (soa_list == NULL) {
+				tlog(TLOG_ERROR, "cannot malloc memory");
+				return -1;
+			}
 
-		memset(soa_list, 0, sizeof(*soa_list));
-		soa_list->qtypeid = atol(argv[i]);
-		if (soa_list->qtypeid == DNS_T_AAAA) {
-			dns_conf_force_AAAA_SOA = 1;
+			memset(soa_list, 0, sizeof(*soa_list));
+			soa_list->qtypeid = atol(tok);
+			if (soa_list->qtypeid == DNS_T_AAAA) {
+				dns_conf_force_AAAA_SOA = 1;
+			}
+			uint32_t key = hash_32_generic(soa_list->qtypeid, 32);
+			hash_add(dns_qtype_soa_table.qtype, &soa_list->node, key);
 		}
-		uint32_t key = hash_32_generic(soa_list->qtypeid, 32);
-		hash_add(dns_qtype_soa_table.qtype, &soa_list->node, key);
 	}
 
 	return 0;

+ 5 - 4
src/dns_server.c

@@ -3961,7 +3961,7 @@ static int _dns_server_pre_process_rule_flags(struct dns_request *request)
 
 	if (flags & DOMAIN_FLAG_ADDR_IGN) {
 		/* ignore this domain */
-		goto out;
+		goto skip_soa_out;
 	}
 
 	/* return specific type of address */
@@ -3969,7 +3969,7 @@ static int _dns_server_pre_process_rule_flags(struct dns_request *request)
 	case DNS_T_A:
 		if (flags & DOMAIN_FLAG_ADDR_IPV4_IGN) {
 			/* ignore this domain for A request */
-			goto out;
+			goto skip_soa_out;
 		}
 
 		if (_dns_server_is_return_soa(request)) {
@@ -3983,7 +3983,7 @@ static int _dns_server_pre_process_rule_flags(struct dns_request *request)
 	case DNS_T_AAAA:
 		if (flags & DOMAIN_FLAG_ADDR_IPV6_IGN) {
 			/* ignore this domain for A request */
-			goto out;
+			goto skip_soa_out;
 		}
 
 		if (_dns_server_is_return_soa(request)) {
@@ -4007,7 +4007,8 @@ static int _dns_server_pre_process_rule_flags(struct dns_request *request)
 	if (_dns_server_is_return_soa(request)) {
 		goto soa;
 	}
-
+skip_soa_out:
+	request->skip_qtype_soa = 1;
 out:
 	return -1;
 

+ 75 - 1
test/cases/test-qtype-soa.cc

@@ -52,7 +52,7 @@ server 127.0.0.1:61053
 log-num 0
 log-console yes
 log-level debug
-force-qtype-SOA 28 65
+force-qtype-SOA 28,65
 cache-persist no)""");
 	smartdns::Client client;
 	ASSERT_TRUE(client.Query("a.com AAAA", 60053));
@@ -77,6 +77,80 @@ cache-persist no)""");
 	EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
 }
 
+TEST_F(QtypeSOA, AAAA_Except)
+{
+	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;
+		} else if (request->qtype == DNS_T_AAAA) {
+			smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::1");
+			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
+dualstack-ip-selection no
+force-qtype-SOA 28
+address /a.com/-
+cache-persist no)""");
+	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(), 3);
+	EXPECT_EQ(client.GetAnswer()[0].GetType(), "AAAA");
+	EXPECT_EQ(client.GetAnswer()[0].GetData(), "2001:db8::1");
+}
+
+TEST_F(QtypeSOA, force_AAAA_SOA_Except)
+{
+	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;
+		} else if (request->qtype == DNS_T_AAAA) {
+			smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::1");
+			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
+dualstack-ip-selection no
+force-AAAA-SOA yes
+address /a.com/-
+cache-persist no)""");
+	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(), 3);
+	EXPECT_EQ(client.GetAnswer()[0].GetType(), "AAAA");
+	EXPECT_EQ(client.GetAnswer()[0].GetData(), "2001:db8::1");
+}
+
 TEST_F(QtypeSOA, force_AAAA_SOA)
 {
 	smartdns::MockServer server_upstream;