test-qtype-soa.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*************************************************************************
  2. *
  3. * Copyright (C) 2018-2025 Ruilin Peng (Nick) <[email protected]>.
  4. *
  5. * smartdns is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * smartdns is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "client.h"
  19. #include "smartdns/dns.h"
  20. #include "include/utils.h"
  21. #include "server.h"
  22. #include "gtest/gtest.h"
  23. class QtypeSOA : public ::testing::Test
  24. {
  25. protected:
  26. virtual void SetUp() {}
  27. virtual void TearDown() {}
  28. };
  29. TEST_F(QtypeSOA, AAAA_HTTPS)
  30. {
  31. smartdns::MockServer server_upstream;
  32. smartdns::Server server;
  33. server_upstream.Start("udp://0.0.0.0:61053", [](struct smartdns::ServerRequestContext *request) {
  34. if (request->qtype == DNS_T_A) {
  35. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  36. smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8");
  37. return smartdns::SERVER_REQUEST_OK;
  38. } else if (request->qtype == DNS_T_AAAA) {
  39. smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::1");
  40. smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::2");
  41. return smartdns::SERVER_REQUEST_OK;
  42. }
  43. return smartdns::SERVER_REQUEST_SOA;
  44. });
  45. server.Start(R"""(bind [::]:60053
  46. server 127.0.0.1:61053
  47. force-qtype-SOA 28,65
  48. )""");
  49. smartdns::Client client;
  50. ASSERT_TRUE(client.Query("a.com AAAA", 60053));
  51. std::cout << client.GetResult() << std::endl;
  52. ASSERT_EQ(client.GetAuthorityNum(), 1);
  53. EXPECT_EQ(client.GetStatus(), "NOERROR");
  54. EXPECT_EQ(client.GetAuthority()[0].GetName(), "a.com");
  55. EXPECT_EQ(client.GetAuthority()[0].GetTTL(), 30);
  56. EXPECT_EQ(client.GetAuthority()[0].GetType(), "SOA");
  57. ASSERT_TRUE(client.Query("a.com -t HTTPS", 60053));
  58. std::cout << client.GetResult() << std::endl;
  59. ASSERT_EQ(client.GetAuthorityNum(), 1);
  60. EXPECT_EQ(client.GetStatus(), "NOERROR");
  61. EXPECT_EQ(client.GetAuthority()[0].GetName(), "a.com");
  62. EXPECT_EQ(client.GetAuthority()[0].GetTTL(), 30);
  63. EXPECT_EQ(client.GetAuthority()[0].GetType(), "SOA");
  64. ASSERT_TRUE(client.Query("a.com A", 60053));
  65. ASSERT_EQ(client.GetAnswerNum(), 1);
  66. EXPECT_EQ(client.GetStatus(), "NOERROR");
  67. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  68. }
  69. TEST_F(QtypeSOA, AAAA_Except)
  70. {
  71. smartdns::MockServer server_upstream;
  72. smartdns::Server server;
  73. server_upstream.Start("udp://0.0.0.0:61053", [](struct smartdns::ServerRequestContext *request) {
  74. if (request->qtype == DNS_T_A) {
  75. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  76. return smartdns::SERVER_REQUEST_OK;
  77. } else if (request->qtype == DNS_T_AAAA) {
  78. smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::1");
  79. return smartdns::SERVER_REQUEST_OK;
  80. }
  81. return smartdns::SERVER_REQUEST_SOA;
  82. });
  83. server.Start(R"""(bind [::]:60053
  84. server 127.0.0.1:61053
  85. dualstack-ip-selection no
  86. force-qtype-SOA 28
  87. address /a.com/-
  88. )""");
  89. smartdns::Client client;
  90. ASSERT_TRUE(client.Query("a.com AAAA", 60053));
  91. std::cout << client.GetResult() << std::endl;
  92. ASSERT_EQ(client.GetAnswerNum(), 1);
  93. EXPECT_EQ(client.GetStatus(), "NOERROR");
  94. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  95. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
  96. EXPECT_EQ(client.GetAnswer()[0].GetType(), "AAAA");
  97. EXPECT_EQ(client.GetAnswer()[0].GetData(), "2001:db8::1");
  98. }
  99. TEST_F(QtypeSOA, force_AAAA_SOA_Except)
  100. {
  101. smartdns::MockServer server_upstream;
  102. smartdns::Server server;
  103. server_upstream.Start("udp://0.0.0.0:61053", [](struct smartdns::ServerRequestContext *request) {
  104. if (request->qtype == DNS_T_A) {
  105. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  106. return smartdns::SERVER_REQUEST_OK;
  107. } else if (request->qtype == DNS_T_AAAA) {
  108. smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::1");
  109. return smartdns::SERVER_REQUEST_OK;
  110. }
  111. return smartdns::SERVER_REQUEST_SOA;
  112. });
  113. server.Start(R"""(bind [::]:60053
  114. server 127.0.0.1:61053
  115. dualstack-ip-selection no
  116. force-AAAA-SOA yes
  117. address /a.com/-
  118. )""");
  119. smartdns::Client client;
  120. ASSERT_TRUE(client.Query("a.com AAAA", 60053));
  121. std::cout << client.GetResult() << std::endl;
  122. ASSERT_EQ(client.GetAnswerNum(), 1);
  123. EXPECT_EQ(client.GetStatus(), "NOERROR");
  124. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  125. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
  126. EXPECT_EQ(client.GetAnswer()[0].GetType(), "AAAA");
  127. EXPECT_EQ(client.GetAnswer()[0].GetData(), "2001:db8::1");
  128. }
  129. TEST_F(QtypeSOA, force_AAAA_SOA)
  130. {
  131. smartdns::MockServer server_upstream;
  132. smartdns::Server server;
  133. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  134. if (request->qtype == DNS_T_A) {
  135. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 700);
  136. return smartdns::SERVER_REQUEST_OK;
  137. } else if (request->qtype == DNS_T_AAAA) {
  138. smartdns::MockServer::AddIP(request, request->domain.c_str(), "64:ff9b::102:304", 700);
  139. return smartdns::SERVER_REQUEST_OK;
  140. }
  141. return smartdns::SERVER_REQUEST_SOA;
  142. });
  143. server.Start(R"""(bind [::]:60053
  144. server 127.0.0.1:61053
  145. speed-check-mode none
  146. force-AAAA-SOA yes
  147. )""");
  148. smartdns::Client client;
  149. ASSERT_TRUE(client.Query("a.com A", 60053));
  150. std::cout << client.GetResult() << std::endl;
  151. ASSERT_EQ(client.GetAnswerNum(), 1);
  152. EXPECT_EQ(client.GetStatus(), "NOERROR");
  153. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  154. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
  155. EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
  156. EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
  157. ASSERT_TRUE(client.Query("a.com AAAA", 60053));
  158. std::cout << client.GetResult() << std::endl;
  159. ASSERT_EQ(client.GetAuthorityNum(), 1);
  160. EXPECT_EQ(client.GetStatus(), "NOERROR");
  161. EXPECT_EQ(client.GetAuthority()[0].GetName(), "a.com");
  162. EXPECT_EQ(client.GetAuthority()[0].GetTTL(), 30);
  163. EXPECT_EQ(client.GetAuthority()[0].GetType(), "SOA");
  164. }
  165. TEST_F(QtypeSOA, bind_force_AAAA_SOA)
  166. {
  167. smartdns::MockServer server_upstream;
  168. smartdns::Server server;
  169. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  170. if (request->qtype == DNS_T_A) {
  171. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 700);
  172. return smartdns::SERVER_REQUEST_OK;
  173. } else if (request->qtype == DNS_T_AAAA) {
  174. smartdns::MockServer::AddIP(request, request->domain.c_str(), "64:ff9b::102:304", 700);
  175. return smartdns::SERVER_REQUEST_OK;
  176. }
  177. return smartdns::SERVER_REQUEST_SOA;
  178. });
  179. server.Start(R"""(
  180. bind [::]:60053
  181. bind [::]:60153 -force-aaaa-soa
  182. server 127.0.0.1:61053
  183. speed-check-mode none
  184. )""");
  185. smartdns::Client client;
  186. ASSERT_TRUE(client.Query("a.com A", 60053));
  187. std::cout << client.GetResult() << std::endl;
  188. ASSERT_EQ(client.GetAnswerNum(), 1);
  189. EXPECT_EQ(client.GetStatus(), "NOERROR");
  190. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  191. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
  192. EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
  193. EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
  194. ASSERT_TRUE(client.Query("a.com AAAA", 60053));
  195. std::cout << client.GetResult() << std::endl;
  196. ASSERT_EQ(client.GetAnswerNum(), 1);
  197. EXPECT_EQ(client.GetStatus(), "NOERROR");
  198. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  199. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
  200. EXPECT_EQ(client.GetAnswer()[0].GetType(), "AAAA");
  201. EXPECT_EQ(client.GetAnswer()[0].GetData(), "64:ff9b::102:304");
  202. ASSERT_TRUE(client.Query("a.com A", 60153));
  203. std::cout << client.GetResult() << std::endl;
  204. ASSERT_EQ(client.GetAnswerNum(), 1);
  205. EXPECT_EQ(client.GetStatus(), "NOERROR");
  206. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  207. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 700);
  208. EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
  209. EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
  210. ASSERT_TRUE(client.Query("a.com AAAA", 60153));
  211. std::cout << client.GetResult() << std::endl;
  212. ASSERT_EQ(client.GetAuthorityNum(), 1);
  213. EXPECT_EQ(client.GetStatus(), "NOERROR");
  214. EXPECT_EQ(client.GetAuthority()[0].GetName(), "a.com");
  215. EXPECT_EQ(client.GetAuthority()[0].GetTTL(), 30);
  216. EXPECT_EQ(client.GetAuthority()[0].GetType(), "SOA");
  217. }
  218. TEST_F(QtypeSOA, HTTPS_SOA)
  219. {
  220. smartdns::MockServer server_upstream;
  221. smartdns::Server server;
  222. std::map<int, int> qid_map;
  223. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  224. if (request->qtype != DNS_T_HTTPS) {
  225. return smartdns::SERVER_REQUEST_SOA;
  226. }
  227. struct dns_packet *packet = request->response_packet;
  228. struct dns_rr_nested svcparam_buffer;
  229. dns_add_HTTPS_start(&svcparam_buffer, packet, DNS_RRS_AN, request->domain.c_str(), 3, 1, "a.com");
  230. const char alph[] = "\x02h2\x05h3-19";
  231. int alph_len = sizeof(alph) - 1;
  232. dns_HTTPS_add_alpn(&svcparam_buffer, alph, alph_len);
  233. dns_HTTPS_add_port(&svcparam_buffer, 443);
  234. unsigned char add_v4[] = {1, 2, 3, 4};
  235. unsigned char *addr[1] = {add_v4};
  236. dns_HTTPS_add_ipv4hint(&svcparam_buffer, addr, 1);
  237. unsigned char ech[] = {0x00, 0x45, 0xfe, 0x0d, 0x00};
  238. dns_HTTPS_add_ech(&svcparam_buffer, (void *)ech, sizeof(ech));
  239. unsigned char add_v6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
  240. addr[0] = add_v6;
  241. dns_HTTPS_add_ipv6hint(&svcparam_buffer, addr, 1);
  242. dns_add_HTTPS_end(&svcparam_buffer);
  243. return smartdns::SERVER_REQUEST_OK;
  244. });
  245. server.Start(R"""(bind [::]:60053
  246. server 127.0.0.1:61053
  247. log-console yes
  248. dualstack-ip-selection no
  249. speed-check-mode none
  250. address /a.com/#
  251. log-level debug
  252. cache-persist no)""");
  253. smartdns::Client client;
  254. ASSERT_TRUE(client.Query("a.com HTTPS", 60053));
  255. std::cout << client.GetResult() << std::endl;
  256. ASSERT_EQ(client.GetAuthorityNum(), 1);
  257. EXPECT_EQ(client.GetStatus(), "NXDOMAIN");
  258. EXPECT_EQ(client.GetAuthority()[0].GetName(), "a.com");
  259. EXPECT_EQ(client.GetAuthority()[0].GetTTL(), 30);
  260. EXPECT_EQ(client.GetAuthority()[0].GetType(), "SOA");
  261. }