test-speed-check.cc 14 KB

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