client_udp.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  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. #define _GNU_SOURCE
  19. #include "smartdns/util.h"
  20. #include "client_socket.h"
  21. #include "client_udp.h"
  22. #include "server_info.h"
  23. #include <net/if.h>
  24. #include <netinet/ip.h>
  25. #include <sys/epoll.h>
  26. #include <sys/ioctl.h>
  27. static int _dns_client_create_socket_udp_proxy(struct dns_server_info *server_info)
  28. {
  29. struct proxy_conn *proxy = NULL;
  30. int fd = -1;
  31. struct epoll_event event;
  32. int ret = -1;
  33. proxy = proxy_conn_new(server_info->proxy_name, server_info->ip, server_info->port, 1, 1);
  34. if (proxy == NULL) {
  35. tlog(TLOG_ERROR, "create proxy failed, %s, proxy: %s", server_info->ip, server_info->proxy_name);
  36. goto errout;
  37. }
  38. fd = proxy_conn_get_fd(proxy);
  39. if (fd < 0) {
  40. tlog(TLOG_ERROR, "get proxy fd failed, %s", server_info->ip);
  41. goto errout;
  42. }
  43. if (server_info->so_mark >= 0) {
  44. unsigned int so_mark = server_info->so_mark;
  45. if (setsockopt(fd, SOL_SOCKET, SO_MARK, &so_mark, sizeof(so_mark)) != 0) {
  46. tlog(TLOG_DEBUG, "set socket mark failed, %s", strerror(errno));
  47. }
  48. }
  49. if (server_info->flags.ifname[0] != '\0') {
  50. struct ifreq ifr;
  51. memset(&ifr, 0, sizeof(struct ifreq));
  52. safe_strncpy(ifr.ifr_name, server_info->flags.ifname, sizeof(ifr.ifr_name));
  53. ioctl(fd, SIOCGIFINDEX, &ifr);
  54. if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(struct ifreq)) < 0) {
  55. tlog(TLOG_ERROR, "bind socket to device %s failed, %s\n", ifr.ifr_name, strerror(errno));
  56. goto errout;
  57. }
  58. }
  59. set_fd_nonblock(fd, 1);
  60. set_sock_keepalive(fd, 30, 3, 5);
  61. if (dns_conf.dns_socket_buff_size > 0) {
  62. setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &dns_conf.dns_socket_buff_size, sizeof(dns_conf.dns_socket_buff_size));
  63. setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &dns_conf.dns_socket_buff_size, sizeof(dns_conf.dns_socket_buff_size));
  64. }
  65. ret = proxy_conn_connect(proxy);
  66. if (ret != 0) {
  67. if (errno != EINPROGRESS) {
  68. tlog(TLOG_DEBUG, "connect %s failed, %s", server_info->ip, strerror(errno));
  69. goto errout;
  70. }
  71. }
  72. server_info->fd = fd;
  73. server_info->status = DNS_SERVER_STATUS_CONNECTING;
  74. server_info->proxy = proxy;
  75. memset(&event, 0, sizeof(event));
  76. event.events = EPOLLIN | EPOLLOUT;
  77. event.data.ptr = server_info;
  78. if (epoll_ctl(client.epoll_fd, EPOLL_CTL_ADD, fd, &event) != 0) {
  79. tlog(TLOG_ERROR, "epoll ctl failed, %s", strerror(errno));
  80. return -1;
  81. }
  82. return 0;
  83. errout:
  84. if (proxy) {
  85. proxy_conn_free(proxy);
  86. }
  87. return -1;
  88. }
  89. int _dns_client_create_socket_udp(struct dns_server_info *server_info)
  90. {
  91. int fd = -1;
  92. struct epoll_event event;
  93. const int on = 1;
  94. const int val = 255;
  95. const int priority = SOCKET_PRIORITY;
  96. const int ip_tos = SOCKET_IP_TOS;
  97. if (server_info->proxy_name[0] != '\0') {
  98. return _dns_client_create_socket_udp_proxy(server_info);
  99. }
  100. fd = socket(server_info->ai_family, SOCK_DGRAM, 0);
  101. if (fd < 0) {
  102. tlog(TLOG_ERROR, "create socket failed, %s", strerror(errno));
  103. goto errout;
  104. }
  105. if (set_fd_nonblock(fd, 1) != 0) {
  106. tlog(TLOG_ERROR, "set socket non block failed, %s", strerror(errno));
  107. goto errout;
  108. }
  109. if (server_info->flags.ifname[0] != '\0') {
  110. struct ifreq ifr;
  111. memset(&ifr, 0, sizeof(struct ifreq));
  112. safe_strncpy(ifr.ifr_name, server_info->flags.ifname, sizeof(ifr.ifr_name));
  113. ioctl(fd, SIOCGIFINDEX, &ifr);
  114. if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(struct ifreq)) < 0) {
  115. tlog(TLOG_ERROR, "bind socket to device %s failed, %s\n", ifr.ifr_name, strerror(errno));
  116. goto errout;
  117. }
  118. }
  119. server_info->fd = fd;
  120. server_info->status = DNS_SERVER_STATUS_CONNECTING;
  121. if (connect(fd, &server_info->addr, server_info->ai_addrlen) != 0) {
  122. if (errno != EINPROGRESS) {
  123. tlog(TLOG_DEBUG, "connect %s failed, %s", server_info->ip, strerror(errno));
  124. goto errout;
  125. }
  126. }
  127. memset(&event, 0, sizeof(event));
  128. event.events = EPOLLIN;
  129. event.data.ptr = server_info;
  130. if (epoll_ctl(client.epoll_fd, EPOLL_CTL_ADD, fd, &event) != 0) {
  131. tlog(TLOG_ERROR, "epoll ctl failed.");
  132. return -1;
  133. }
  134. if (server_info->so_mark >= 0) {
  135. unsigned int so_mark = server_info->so_mark;
  136. if (setsockopt(fd, SOL_SOCKET, SO_MARK, &so_mark, sizeof(so_mark)) != 0) {
  137. tlog(TLOG_DEBUG, "set socket mark failed, %s", strerror(errno));
  138. }
  139. }
  140. setsockopt(server_info->fd, IPPROTO_IP, IP_RECVTTL, &on, sizeof(on));
  141. setsockopt(server_info->fd, SOL_IP, IP_TTL, &val, sizeof(val));
  142. setsockopt(server_info->fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority));
  143. setsockopt(server_info->fd, IPPROTO_IP, IP_TOS, &ip_tos, sizeof(ip_tos));
  144. if (server_info->ai_family == AF_INET6) {
  145. /* for receiving ip ttl value */
  146. setsockopt(server_info->fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on));
  147. setsockopt(server_info->fd, IPPROTO_IPV6, IPV6_2292HOPLIMIT, &on, sizeof(on));
  148. setsockopt(server_info->fd, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on));
  149. }
  150. if (dns_conf.dns_socket_buff_size > 0) {
  151. setsockopt(server_info->fd, SOL_SOCKET, SO_SNDBUF, &dns_conf.dns_socket_buff_size,
  152. sizeof(dns_conf.dns_socket_buff_size));
  153. setsockopt(server_info->fd, SOL_SOCKET, SO_RCVBUF, &dns_conf.dns_socket_buff_size,
  154. sizeof(dns_conf.dns_socket_buff_size));
  155. }
  156. return 0;
  157. errout:
  158. if (fd > 0) {
  159. close(fd);
  160. }
  161. server_info->fd = -1;
  162. server_info->status = DNS_SERVER_STATUS_DISCONNECTED;
  163. return -1;
  164. }
  165. static int _dns_client_process_send_udp_buffer(struct dns_server_info *server_info, struct epoll_event *event,
  166. unsigned long now)
  167. {
  168. int send_len = 0;
  169. if (server_info->send_buff.len <= 0 || server_info->status != DNS_SERVER_STATUS_CONNECTED) {
  170. return 0;
  171. }
  172. while (server_info->send_buff.len - send_len > 0) {
  173. int ret = 0;
  174. int packet_len = 0;
  175. packet_len = *(int *)(server_info->send_buff.data + send_len);
  176. send_len += sizeof(packet_len);
  177. if (packet_len > server_info->send_buff.len - 1) {
  178. goto errout;
  179. }
  180. ret = _dns_client_send_udp(server_info, server_info->send_buff.data + send_len, packet_len);
  181. if (ret < 0) {
  182. tlog(TLOG_ERROR, "sendto failed, %s", strerror(errno));
  183. goto errout;
  184. }
  185. send_len += packet_len;
  186. }
  187. server_info->send_buff.len -= send_len;
  188. if (server_info->send_buff.len < 0) {
  189. server_info->send_buff.len = 0;
  190. }
  191. return 0;
  192. errout:
  193. pthread_mutex_lock(&client.server_list_lock);
  194. server_info->recv_buff.len = 0;
  195. server_info->send_buff.len = 0;
  196. _dns_client_close_socket(server_info);
  197. pthread_mutex_unlock(&client.server_list_lock);
  198. return -1;
  199. }
  200. static int _dns_client_process_udp_proxy(struct dns_server_info *server_info, struct epoll_event *event,
  201. unsigned long now)
  202. {
  203. struct sockaddr_storage from;
  204. socklen_t from_len = sizeof(from);
  205. char from_host[DNS_MAX_CNAME_LEN];
  206. unsigned char inpacket[DNS_IN_PACKSIZE];
  207. int len = 0;
  208. int ret = 0;
  209. _dns_client_process_send_udp_buffer(server_info, event, now);
  210. if (!(event->events & EPOLLIN)) {
  211. return 0;
  212. }
  213. len = proxy_conn_recvfrom(server_info->proxy, inpacket, sizeof(inpacket), 0, (struct sockaddr *)&from, &from_len);
  214. if (len < 0) {
  215. if (errno == EAGAIN || errno == EWOULDBLOCK) {
  216. return 0;
  217. }
  218. if (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH) {
  219. tlog(TLOG_DEBUG, "recvfrom %s failed, %s\n", server_info->ip, strerror(errno));
  220. goto errout;
  221. }
  222. tlog(TLOG_ERROR, "recvfrom %s failed, %s\n", server_info->ip, strerror(errno));
  223. goto errout;
  224. } else if (len == 0) {
  225. pthread_mutex_lock(&server_info->lock);
  226. _dns_client_close_socket(server_info);
  227. server_info->recv_buff.len = 0;
  228. if (server_info->send_buff.len > 0) {
  229. /* still remain request data, reconnect and send*/
  230. ret = _dns_client_create_socket(server_info);
  231. } else {
  232. ret = 0;
  233. }
  234. pthread_mutex_unlock(&server_info->lock);
  235. tlog(TLOG_DEBUG, "peer close, %s:%d", server_info->ip, server_info->port);
  236. return ret;
  237. }
  238. int latency = get_tick_count() - server_info->send_tick;
  239. tlog(TLOG_DEBUG, "recv udp packet from %s, len: %d, latency: %d",
  240. get_host_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), len, latency);
  241. if (latency < server_info->drop_packet_latency_ms) {
  242. tlog(TLOG_DEBUG, "drop packet from %s, latency: %d", from_host, latency);
  243. return 0;
  244. }
  245. if (server_info->status == DNS_SERVER_STATUS_CONNECTING) {
  246. server_info->status = DNS_SERVER_STATUS_CONNECTED;
  247. }
  248. /* update recv time */
  249. time(&server_info->last_recv);
  250. /* processing dns packet */
  251. if (_dns_client_recv(server_info, inpacket, len, (struct sockaddr *)&from, from_len) != 0) {
  252. return -1;
  253. }
  254. return 0;
  255. errout:
  256. pthread_mutex_lock(&server_info->lock);
  257. server_info->recv_buff.len = 0;
  258. server_info->send_buff.len = 0;
  259. _dns_client_close_socket(server_info);
  260. pthread_mutex_unlock(&server_info->lock);
  261. return -1;
  262. }
  263. int _dns_client_process_udp(struct dns_server_info *server_info, struct epoll_event *event, unsigned long now)
  264. {
  265. int len = 0;
  266. unsigned char inpacket[DNS_IN_PACKSIZE];
  267. struct sockaddr_storage from;
  268. socklen_t from_len = sizeof(from);
  269. char from_host[DNS_MAX_CNAME_LEN];
  270. struct msghdr msg;
  271. struct iovec iov;
  272. char ans_data[4096];
  273. int ttl = 0;
  274. struct cmsghdr *cmsg = NULL;
  275. if (server_info->proxy) {
  276. return _dns_client_process_udp_proxy(server_info, event, now);
  277. }
  278. memset(&msg, 0, sizeof(msg));
  279. iov.iov_base = (char *)inpacket;
  280. iov.iov_len = sizeof(inpacket);
  281. msg.msg_name = &from;
  282. msg.msg_namelen = sizeof(from);
  283. msg.msg_iov = &iov;
  284. msg.msg_iovlen = 1;
  285. msg.msg_control = ans_data;
  286. msg.msg_controllen = sizeof(ans_data);
  287. len = recvmsg(server_info->fd, &msg, MSG_DONTWAIT);
  288. if (len < 0) {
  289. if (errno == EAGAIN || errno == EWOULDBLOCK) {
  290. return 0;
  291. }
  292. server_info->prohibit = 1;
  293. if (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EHOSTUNREACH) {
  294. tlog(TLOG_DEBUG, "recvfrom %s failed, %s\n", server_info->ip, strerror(errno));
  295. goto errout;
  296. }
  297. tlog(TLOG_ERROR, "recvfrom %s failed, %s\n", server_info->ip, strerror(errno));
  298. goto errout;
  299. }
  300. from_len = msg.msg_namelen;
  301. /* Get the TTL of the IP header */
  302. for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
  303. if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) {
  304. if (cmsg->cmsg_len >= sizeof(int)) {
  305. int *ttlPtr = (int *)CMSG_DATA(cmsg);
  306. ttl = *ttlPtr;
  307. }
  308. } else if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_HOPLIMIT) {
  309. if (cmsg->cmsg_len >= sizeof(int)) {
  310. int *ttlPtr = (int *)CMSG_DATA(cmsg);
  311. ttl = *ttlPtr;
  312. }
  313. }
  314. }
  315. int from_port = from.ss_family == AF_INET ? ntohs(((struct sockaddr_in *)&from)->sin_port)
  316. : ntohs(((struct sockaddr_in6 *)&from)->sin6_port);
  317. int latency = get_tick_count() - server_info->send_tick;
  318. tlog(TLOG_DEBUG, "recv udp packet from %s:%d, len: %d, ttl: %d, latency: %d",
  319. get_host_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), from_port, len, ttl, latency);
  320. /* update recv time */
  321. time(&server_info->last_recv);
  322. if (latency > 0 && latency < server_info->drop_packet_latency_ms) {
  323. tlog(TLOG_DEBUG, "drop packet from %s, latency: %d", from_host, latency);
  324. return 0;
  325. }
  326. if (server_info->status == DNS_SERVER_STATUS_CONNECTING) {
  327. server_info->status = DNS_SERVER_STATUS_CONNECTED;
  328. }
  329. /* processing dns packet */
  330. if (_dns_client_recv(server_info, inpacket, len, (struct sockaddr *)&from, from_len) != 0) {
  331. return -1;
  332. }
  333. return 0;
  334. errout:
  335. pthread_mutex_lock(&client.server_list_lock);
  336. server_info->recv_buff.len = 0;
  337. server_info->send_buff.len = 0;
  338. _dns_client_close_socket(server_info);
  339. pthread_mutex_unlock(&client.server_list_lock);
  340. return -1;
  341. }
  342. int _dns_client_send_udp(struct dns_server_info *server_info, void *packet, int len)
  343. {
  344. int send_len = 0;
  345. const struct sockaddr *addr = &server_info->addr;
  346. socklen_t addrlen = server_info->ai_addrlen;
  347. int ret = 0;
  348. if (server_info->fd <= 0) {
  349. return -1;
  350. }
  351. if (server_info->proxy) {
  352. if (server_info->status != DNS_SERVER_STATUS_CONNECTED) {
  353. /*set packet len*/
  354. _dns_client_copy_data_to_buffer(server_info, &len, sizeof(len));
  355. return _dns_client_copy_data_to_buffer(server_info, packet, len);
  356. }
  357. send_len = proxy_conn_sendto(server_info->proxy, packet, len, 0, addr, addrlen);
  358. if (send_len != len) {
  359. _dns_client_close_socket(server_info);
  360. server_info->recv_buff.len = 0;
  361. if (server_info->send_buff.len > 0) {
  362. /* still remain request data, reconnect and send*/
  363. ret = _dns_client_create_socket(server_info);
  364. } else {
  365. ret = 0;
  366. }
  367. if (ret != 0) {
  368. return -1;
  369. }
  370. _dns_client_copy_data_to_buffer(server_info, &len, sizeof(len));
  371. return _dns_client_copy_data_to_buffer(server_info, packet, len);
  372. }
  373. return 0;
  374. }
  375. send_len = sendto(server_info->fd, packet, len, 0, NULL, 0);
  376. if (send_len != len) {
  377. goto errout;
  378. }
  379. return 0;
  380. errout:
  381. return -1;
  382. }
  383. void _dns_client_check_udp_nat(struct dns_query_struct *query)
  384. {
  385. struct dns_server_info *server_info = NULL;
  386. struct dns_server_group_member *group_member = NULL;
  387. /* For udp nat case.
  388. * when router reconnect to internet, udp port may always marked as UNREPLIED.
  389. * dns query will timeout, and cannot reconnect again,
  390. * create a new socket to communicate.
  391. */
  392. pthread_mutex_lock(&client.server_list_lock);
  393. list_for_each_entry(group_member, &query->server_group->head, list)
  394. {
  395. server_info = group_member->server;
  396. if (server_info->type != DNS_SERVER_UDP) {
  397. continue;
  398. }
  399. if (server_info->last_send - 5 > server_info->last_recv) {
  400. server_info->recv_buff.len = 0;
  401. server_info->send_buff.len = 0;
  402. tlog(TLOG_DEBUG, "query server %s timeout.", server_info->ip);
  403. _dns_client_close_socket(server_info);
  404. }
  405. }
  406. pthread_mutex_unlock(&client.server_list_lock);
  407. }