test-speed-check.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /*************************************************************************
  2. *
  3. * Copyright (C) 2018-2023 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 "dns.h"
  20. #include "include/utils.h"
  21. #include "server.h"
  22. #include "util.h"
  23. #include "gtest/gtest.h"
  24. #include <fstream>
  25. class SpeedCheck : public ::testing::Test
  26. {
  27. protected:
  28. virtual void SetUp() {}
  29. virtual void TearDown() {}
  30. };
  31. TEST_F(SpeedCheck, response_mode)
  32. {
  33. smartdns::MockServer server_upstream;
  34. smartdns::Server server;
  35. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  36. if (request->qtype == DNS_T_A) {
  37. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  38. smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8");
  39. return smartdns::SERVER_REQUEST_OK;
  40. }
  41. return smartdns::SERVER_REQUEST_SOA;
  42. });
  43. server.Start(R"""(bind [::]:60053
  44. server 127.0.0.1:61053
  45. log-num 0
  46. log-console yes
  47. response-mode first-ping
  48. domain-rules /a.com/ -r fastest-response
  49. log-level debug
  50. cache-persist no)""");
  51. smartdns::Client client;
  52. ASSERT_TRUE(client.Query("b.com", 60053));
  53. std::cout << client.GetResult() << std::endl;
  54. ASSERT_EQ(client.GetAnswerNum(), 1);
  55. EXPECT_EQ(client.GetStatus(), "NOERROR");
  56. EXPECT_GT(client.GetQueryTime(), 100);
  57. EXPECT_EQ(client.GetAnswer()[0].GetName(), "b.com");
  58. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
  59. ASSERT_TRUE(client.Query("a.com", 60053));
  60. std::cout << client.GetResult() << std::endl;
  61. ASSERT_EQ(client.GetAnswerNum(), 2);
  62. EXPECT_EQ(client.GetStatus(), "NOERROR");
  63. EXPECT_LT(client.GetQueryTime(), 10);
  64. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  65. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
  66. EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
  67. EXPECT_EQ(client.GetAnswer()[1].GetData(), "5.6.7.8");
  68. }
  69. TEST_F(SpeedCheck, none)
  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. smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8");
  77. return smartdns::SERVER_REQUEST_OK;
  78. }
  79. return smartdns::SERVER_REQUEST_SOA;
  80. });
  81. server.Start(R"""(bind [::]:60053
  82. server 127.0.0.1:61053
  83. log-num 0
  84. log-console yes
  85. speed-check-mode none
  86. log-level debug
  87. cache-persist no)""");
  88. smartdns::Client client;
  89. ASSERT_TRUE(client.Query("b.com", 60053));
  90. std::cout << client.GetResult() << std::endl;
  91. ASSERT_EQ(client.GetAnswerNum(), 2);
  92. EXPECT_EQ(client.GetStatus(), "NOERROR");
  93. EXPECT_LT(client.GetQueryTime(), 20);
  94. EXPECT_EQ(client.GetAnswer()[0].GetName(), "b.com");
  95. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
  96. ASSERT_TRUE(client.Query("a.com", 60053));
  97. std::cout << client.GetResult() << std::endl;
  98. ASSERT_EQ(client.GetAnswerNum(), 2);
  99. EXPECT_EQ(client.GetStatus(), "NOERROR");
  100. EXPECT_LT(client.GetQueryTime(), 20);
  101. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  102. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
  103. EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
  104. EXPECT_EQ(client.GetAnswer()[1].GetData(), "5.6.7.8");
  105. }
  106. TEST_F(SpeedCheck, domain_rules_none)
  107. {
  108. smartdns::MockServer server_upstream;
  109. smartdns::Server server;
  110. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  111. if (request->qtype == DNS_T_A) {
  112. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  113. smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8");
  114. return smartdns::SERVER_REQUEST_OK;
  115. }
  116. return smartdns::SERVER_REQUEST_SOA;
  117. });
  118. server.Start(R"""(bind [::]:60053
  119. server 127.0.0.1:61053
  120. log-num 0
  121. log-console yes
  122. domain-rules /a.com/ -c none
  123. log-level debug
  124. cache-persist no)""");
  125. smartdns::Client client;
  126. ASSERT_TRUE(client.Query("b.com", 60053));
  127. std::cout << client.GetResult() << std::endl;
  128. ASSERT_EQ(client.GetAnswerNum(), 1);
  129. EXPECT_EQ(client.GetStatus(), "NOERROR");
  130. EXPECT_GT(client.GetQueryTime(), 200);
  131. EXPECT_EQ(client.GetAnswer()[0].GetName(), "b.com");
  132. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
  133. ASSERT_TRUE(client.Query("a.com", 60053));
  134. std::cout << client.GetResult() << std::endl;
  135. ASSERT_EQ(client.GetAnswerNum(), 2);
  136. EXPECT_EQ(client.GetStatus(), "NOERROR");
  137. EXPECT_LT(client.GetQueryTime(), 20);
  138. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  139. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
  140. EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
  141. EXPECT_EQ(client.GetAnswer()[1].GetData(), "5.6.7.8");
  142. }
  143. TEST_F(SpeedCheck, only_ping)
  144. {
  145. smartdns::MockServer server_upstream;
  146. smartdns::Server server;
  147. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  148. if (request->qtype == DNS_T_A) {
  149. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  150. smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8");
  151. return smartdns::SERVER_REQUEST_OK;
  152. }
  153. return smartdns::SERVER_REQUEST_SOA;
  154. });
  155. server.Start(R"""(bind [::]:60053
  156. server 127.0.0.1:61053
  157. log-num 0
  158. log-console yes
  159. speed-check-mode ping
  160. log-level debug
  161. cache-persist no)""");
  162. smartdns::Client client;
  163. ASSERT_TRUE(client.Query("b.com", 60053));
  164. std::cout << client.GetResult() << std::endl;
  165. ASSERT_EQ(client.GetAnswerNum(), 1);
  166. EXPECT_EQ(client.GetStatus(), "NOERROR");
  167. EXPECT_LT(client.GetQueryTime(), 1200);
  168. EXPECT_EQ(client.GetAnswer()[0].GetName(), "b.com");
  169. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
  170. }
  171. TEST_F(SpeedCheck, no_ping_fallback_tcp)
  172. {
  173. smartdns::MockServer server_upstream;
  174. smartdns::Server server;
  175. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  176. if (request->qtype == DNS_T_A) {
  177. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  178. smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8");
  179. return smartdns::SERVER_REQUEST_OK;
  180. }
  181. return smartdns::SERVER_REQUEST_SOA;
  182. });
  183. server.MockPing(PING_TYPE_ICMP, "1.2.3.4", 60, 1000);
  184. server.MockPing(PING_TYPE_TCP, "5.6.7.8:80", 60, 100);
  185. server.Start(R"""(bind [::]:60053
  186. server 127.0.0.1:61053
  187. log-num 0
  188. log-console yes
  189. speed-check-mode ping,tcp:80
  190. log-level debug
  191. cache-persist no)""");
  192. smartdns::Client client;
  193. ASSERT_TRUE(client.Query("a.com", 60053));
  194. std::cout << client.GetResult() << std::endl;
  195. ASSERT_EQ(client.GetAnswerNum(), 1);
  196. EXPECT_EQ(client.GetStatus(), "NOERROR");
  197. EXPECT_LT(client.GetQueryTime(), 500);
  198. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  199. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
  200. EXPECT_EQ(client.GetAnswer()[0].GetData(), "5.6.7.8");
  201. }
  202. TEST_F(SpeedCheck, tcp_faster_than_ping)
  203. {
  204. smartdns::MockServer server_upstream;
  205. smartdns::Server server;
  206. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  207. if (request->qtype == DNS_T_A) {
  208. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  209. smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8");
  210. return smartdns::SERVER_REQUEST_OK;
  211. }
  212. return smartdns::SERVER_REQUEST_SOA;
  213. });
  214. server.MockPing(PING_TYPE_ICMP, "1.2.3.4", 60, 350);
  215. server.MockPing(PING_TYPE_TCP, "5.6.7.8:80", 60, 10);
  216. server.Start(R"""(bind [::]:60053
  217. server 127.0.0.1:61053
  218. log-num 0
  219. log-console yes
  220. speed-check-mode ping,tcp:80
  221. log-level debug
  222. cache-persist no)""");
  223. smartdns::Client client;
  224. ASSERT_TRUE(client.Query("a.com", 60053));
  225. std::cout << client.GetResult() << std::endl;
  226. ASSERT_EQ(client.GetAnswerNum(), 1);
  227. EXPECT_EQ(client.GetStatus(), "NOERROR");
  228. EXPECT_LT(client.GetQueryTime(), 500);
  229. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  230. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
  231. EXPECT_EQ(client.GetAnswer()[0].GetData(), "5.6.7.8");
  232. }
  233. TEST_F(SpeedCheck, fastest_ip)
  234. {
  235. smartdns::MockServer server_upstream;
  236. smartdns::Server server;
  237. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  238. if (request->qtype == DNS_T_A) {
  239. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  240. smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8");
  241. return smartdns::SERVER_REQUEST_OK;
  242. }
  243. return smartdns::SERVER_REQUEST_SOA;
  244. });
  245. server.MockPing(PING_TYPE_ICMP, "1.2.3.4", 60, 100);
  246. server.MockPing(PING_TYPE_ICMP, "5.6.7.8", 60, 110);
  247. server.Start(R"""(bind [::]:60053
  248. server 127.0.0.1:61053
  249. log-num 0
  250. log-console yes
  251. speed-check-mode ping
  252. dualstack-ip-selection no
  253. log-level debug
  254. cache-persist no)""");
  255. smartdns::Client client;
  256. ASSERT_TRUE(client.Query("b.com", 60053));
  257. std::cout << client.GetResult() << std::endl;
  258. ASSERT_EQ(client.GetAnswerNum(), 1);
  259. EXPECT_EQ(client.GetStatus(), "NOERROR");
  260. EXPECT_LT(client.GetQueryTime(), 200);
  261. EXPECT_EQ(client.GetAnswer()[0].GetName(), "b.com");
  262. EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
  263. EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
  264. usleep(220 * 1000);
  265. ASSERT_TRUE(client.Query("b.com", 60053));
  266. std::cout << client.GetResult() << std::endl;
  267. ASSERT_EQ(client.GetAnswerNum(), 2);
  268. EXPECT_EQ(client.GetStatus(), "NOERROR");
  269. EXPECT_LT(client.GetQueryTime(), 20);
  270. EXPECT_EQ(client.GetAnswer()[0].GetName(), "b.com");
  271. EXPECT_GT(client.GetAnswer()[0].GetTTL(), 597);
  272. EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
  273. EXPECT_EQ(client.GetAnswer()[1].GetData(), "5.6.7.8");
  274. }
  275. TEST_F(SpeedCheck, unreach_best_ipv4)
  276. {
  277. smartdns::MockServer server_upstream;
  278. smartdns::MockServer server_upstream2;
  279. smartdns::Server server;
  280. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  281. if (request->qtype == DNS_T_A) {
  282. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  283. smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8");
  284. return smartdns::SERVER_REQUEST_OK;
  285. }
  286. return smartdns::SERVER_REQUEST_SOA;
  287. });
  288. server_upstream2.Start("udp://0.0.0.0:62053", [&](struct smartdns::ServerRequestContext *request) {
  289. if (request->qtype == DNS_T_A) {
  290. smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4");
  291. smartdns::MockServer::AddIP(request, request->domain.c_str(), "9.10.11.12");
  292. return smartdns::SERVER_REQUEST_OK;
  293. }
  294. return smartdns::SERVER_REQUEST_SOA;
  295. });
  296. server.MockPing(PING_TYPE_ICMP, "1.2.3.4", 60, 10000);
  297. server.MockPing(PING_TYPE_ICMP, "5.6.7.8", 60, 10000);
  298. server.MockPing(PING_TYPE_ICMP, "9.10.11.12", 60, 10000);
  299. server.Start(R"""(bind [::]:60053
  300. server 127.0.0.1:61053
  301. server 127.0.0.1:62053
  302. log-num 0
  303. log-console yes
  304. speed-check-mode ping
  305. dualstack-ip-selection no
  306. log-level debug
  307. cache-persist no)""");
  308. smartdns::Client client;
  309. ASSERT_TRUE(client.Query("a.com", 60053));
  310. std::cout << client.GetResult() << std::endl;
  311. ASSERT_EQ(client.GetAnswerNum(), 1);
  312. EXPECT_EQ(client.GetStatus(), "NOERROR");
  313. EXPECT_LT(client.GetQueryTime(), 1200);
  314. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  315. EXPECT_GT(client.GetAnswer()[0].GetTTL(), 597);
  316. EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
  317. }
  318. TEST_F(SpeedCheck, unreach_best_ipv6)
  319. {
  320. smartdns::MockServer server_upstream;
  321. smartdns::MockServer server_upstream2;
  322. smartdns::Server server;
  323. server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
  324. if (request->qtype == DNS_T_AAAA) {
  325. smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::1");
  326. smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::2");
  327. return smartdns::SERVER_REQUEST_OK;
  328. }
  329. return smartdns::SERVER_REQUEST_SOA;
  330. });
  331. server_upstream2.Start("udp://0.0.0.0:62053", [&](struct smartdns::ServerRequestContext *request) {
  332. if (request->qtype == DNS_T_AAAA) {
  333. smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::2");
  334. smartdns::MockServer::AddIP(request, request->domain.c_str(), "2001:db8::3");
  335. return smartdns::SERVER_REQUEST_OK;
  336. }
  337. return smartdns::SERVER_REQUEST_SOA;
  338. });
  339. server.MockPing(PING_TYPE_ICMP, "2001:db8::1", 60, 10000);
  340. server.MockPing(PING_TYPE_ICMP, "2001:db8::2", 60, 10000);
  341. server.MockPing(PING_TYPE_ICMP, "2001:db8::3", 60, 10000);
  342. server.Start(R"""(bind [::]:60053
  343. server 127.0.0.1:61053
  344. server 127.0.0.1:62053
  345. log-num 0
  346. log-console yes
  347. speed-check-mode ping
  348. dualstack-ip-selection no
  349. log-level debug
  350. cache-persist no)""");
  351. smartdns::Client client;
  352. ASSERT_TRUE(client.Query("a.com AAAA", 60053));
  353. std::cout << client.GetResult() << std::endl;
  354. ASSERT_EQ(client.GetAnswerNum(), 1);
  355. EXPECT_EQ(client.GetStatus(), "NOERROR");
  356. EXPECT_LT(client.GetQueryTime(), 1200);
  357. EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
  358. EXPECT_GT(client.GetAnswer()[0].GetTTL(), 597);
  359. EXPECT_EQ(client.GetAnswer()[0].GetData(), "2001:db8::2");
  360. }