You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1108 lines
33KB

  1. /*
  2. * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit).
  5. *
  6. * Use of this source code is governed by MIT license that can be found in the
  7. * LICENSE file in the root of the source tree. All contributing project authors
  8. * may be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include <fcntl.h>
  11. #include <assert.h>
  12. #include <cstdio>
  13. #include <cstring>
  14. #include <mutex>
  15. #include <string>
  16. #include <unordered_map>
  17. #include "sockutil.h"
  18. #include "Util/util.h"
  19. #include "Util/logger.h"
  20. #include "Util/uv_errno.h"
  21. #include "Util/onceToken.h"
  22. #if defined (__APPLE__)
  23. #include <ifaddrs.h>
  24. #endif
  25. using namespace std;
  26. namespace toolkit {
  27. #if defined(_WIN32)
  28. static onceToken g_token([]() {
  29. WORD wVersionRequested = MAKEWORD(2, 2);
  30. WSADATA wsaData;
  31. WSAStartup(wVersionRequested, &wsaData);
  32. }, []() {
  33. WSACleanup();
  34. });
  35. int ioctl(int fd, long cmd, u_long *ptr) {
  36. return ioctlsocket(fd, cmd, ptr);
  37. }
  38. int close(int fd) {
  39. return closesocket(fd);
  40. }
  41. #if (_WIN32_WINNT < _WIN32_WINNT_VISTA)
  42. const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) {
  43. struct sockaddr_storage ss;
  44. unsigned long s = size;
  45. ZeroMemory(&ss, sizeof(ss));
  46. ss.ss_family = af;
  47. switch (af) {
  48. case AF_INET:
  49. ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
  50. break;
  51. case AF_INET6:
  52. ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src;
  53. break;
  54. default:
  55. return NULL;
  56. }
  57. /* cannot direclty use &size because of strict aliasing rules */
  58. return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0) ? dst : NULL;
  59. }
  60. int inet_pton(int af, const char *src, void *dst) {
  61. struct sockaddr_storage ss;
  62. int size = sizeof(ss);
  63. char src_copy[INET6_ADDRSTRLEN + 1];
  64. ZeroMemory(&ss, sizeof(ss));
  65. /* stupid non-const API */
  66. strncpy(src_copy, src, INET6_ADDRSTRLEN + 1);
  67. src_copy[INET6_ADDRSTRLEN] = 0;
  68. if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) {
  69. switch (af) {
  70. case AF_INET:
  71. *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
  72. return 1;
  73. case AF_INET6:
  74. *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
  75. return 1;
  76. }
  77. }
  78. return 0;
  79. }
  80. #endif
  81. #endif // defined(_WIN32)
  82. static inline string my_inet_ntop(int af, const void *addr) {
  83. string ret;
  84. ret.resize(128);
  85. if (!inet_ntop(af, const_cast<void*>(addr), (char *) ret.data(), ret.size())) {
  86. ret.clear();
  87. } else {
  88. ret.resize(strlen(ret.data()));
  89. }
  90. return ret;
  91. }
  92. static inline bool support_ipv6_l() {
  93. auto fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
  94. if (fd == -1) {
  95. return false;
  96. }
  97. close(fd);
  98. return true;
  99. }
  100. static inline bool support_ipv6() {
  101. static auto flag = support_ipv6_l();
  102. return flag;
  103. }
  104. string SockUtil::inet_ntoa(const struct in_addr &addr) {
  105. return my_inet_ntop(AF_INET, &addr);
  106. }
  107. std::string SockUtil::inet_ntoa(const struct in6_addr &addr) {
  108. return my_inet_ntop(AF_INET6, &addr);
  109. }
  110. std::string SockUtil::inet_ntoa(const struct sockaddr *addr) {
  111. switch (addr->sa_family) {
  112. case AF_INET: return SockUtil::inet_ntoa(((struct sockaddr_in *)addr)->sin_addr);
  113. case AF_INET6: {
  114. if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)addr)->sin6_addr)) {
  115. struct in_addr addr4;
  116. memcpy(&addr4, 12 + (char *)&(((struct sockaddr_in6 *)addr)->sin6_addr), 4);
  117. return SockUtil::inet_ntoa(addr4);
  118. }
  119. return SockUtil::inet_ntoa(((struct sockaddr_in6 *)addr)->sin6_addr);
  120. }
  121. default: assert(false); return "";
  122. }
  123. }
  124. uint16_t SockUtil::inet_port(const struct sockaddr *addr) {
  125. switch (addr->sa_family) {
  126. case AF_INET: return ntohs(((struct sockaddr_in *)addr)->sin_port);
  127. case AF_INET6: return ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
  128. default: assert(false); return 0;
  129. }
  130. }
  131. int SockUtil::setCloseWait(int fd, int second) {
  132. linger m_sLinger;
  133. //在调用closesocket()时还有数据未发送完,允许等待
  134. // 若m_sLinger.l_onoff=0;则调用closesocket()后强制关闭
  135. m_sLinger.l_onoff = (second > 0);
  136. m_sLinger.l_linger = second; //设置等待时间为x秒
  137. int ret = setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &m_sLinger, sizeof(linger));
  138. if (ret == -1) {
  139. #ifndef _WIN32
  140. TraceL << "setsockopt SO_LINGER failed";
  141. #endif
  142. }
  143. return ret;
  144. }
  145. int SockUtil::setNoDelay(int fd, bool on) {
  146. int opt = on ? 1 : 0;
  147. int ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &opt, static_cast<socklen_t>(sizeof(opt)));
  148. if (ret == -1) {
  149. TraceL << "setsockopt TCP_NODELAY failed";
  150. }
  151. return ret;
  152. }
  153. int SockUtil::setReuseable(int fd, bool on, bool reuse_port) {
  154. int opt = on ? 1 : 0;
  155. int ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, static_cast<socklen_t>(sizeof(opt)));
  156. if (ret == -1) {
  157. TraceL << "setsockopt SO_REUSEADDR failed";
  158. return ret;
  159. }
  160. #if defined(SO_REUSEPORT)
  161. if (reuse_port) {
  162. ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *) &opt, static_cast<socklen_t>(sizeof(opt)));
  163. if (ret == -1) {
  164. TraceL << "setsockopt SO_REUSEPORT failed";
  165. }
  166. }
  167. #endif
  168. return ret;
  169. }
  170. int SockUtil::setBroadcast(int fd, bool on) {
  171. int opt = on ? 1 : 0;
  172. int ret = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *) &opt, static_cast<socklen_t>(sizeof(opt)));
  173. if (ret == -1) {
  174. TraceL << "setsockopt SO_BROADCAST failed";
  175. }
  176. return ret;
  177. }
  178. int SockUtil::setKeepAlive(int fd, bool on) {
  179. int opt = on ? 1 : 0;
  180. int ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, static_cast<socklen_t>(sizeof(opt)));
  181. if (ret == -1) {
  182. TraceL << "setsockopt SO_KEEPALIVE failed";
  183. }
  184. return ret;
  185. }
  186. int SockUtil::setCloExec(int fd, bool on) {
  187. #if !defined(_WIN32)
  188. int flags = fcntl(fd, F_GETFD);
  189. if (flags == -1) {
  190. TraceL << "fcntl F_GETFD failed";
  191. return -1;
  192. }
  193. if (on) {
  194. flags |= FD_CLOEXEC;
  195. } else {
  196. int cloexec = FD_CLOEXEC;
  197. flags &= ~cloexec;
  198. }
  199. int ret = fcntl(fd, F_SETFD, flags);
  200. if (ret == -1) {
  201. TraceL << "fcntl F_SETFD failed";
  202. return -1;
  203. }
  204. return ret;
  205. #else
  206. return -1;
  207. #endif
  208. }
  209. int SockUtil::setNoSigpipe(int fd) {
  210. #if defined(SO_NOSIGPIPE)
  211. int set = 1;
  212. auto ret = setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (char *) &set, sizeof(int));
  213. if (ret == -1) {
  214. TraceL << "setsockopt SO_NOSIGPIPE failed";
  215. }
  216. return ret;
  217. #else
  218. return -1;
  219. #endif
  220. }
  221. int SockUtil::setNoBlocked(int fd, bool noblock) {
  222. #if defined(_WIN32)
  223. unsigned long ul = noblock;
  224. #else
  225. int ul = noblock;
  226. #endif //defined(_WIN32)
  227. int ret = ioctl(fd, FIONBIO, &ul); //设置为非阻塞模式
  228. if (ret == -1) {
  229. TraceL << "ioctl FIONBIO failed";
  230. }
  231. return ret;
  232. }
  233. int SockUtil::setRecvBuf(int fd, int size) {
  234. int ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof(size));
  235. if (ret == -1) {
  236. TraceL << "setsockopt SO_RCVBUF failed";
  237. }
  238. return ret;
  239. }
  240. int SockUtil::setSendBuf(int fd, int size) {
  241. int ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof(size));
  242. if (ret == -1) {
  243. TraceL << "setsockopt SO_SNDBUF failed";
  244. }
  245. return ret;
  246. }
  247. class DnsCache {
  248. public:
  249. static DnsCache &Instance() {
  250. static DnsCache instance;
  251. return instance;
  252. }
  253. bool getDomainIP(const char *host, sockaddr_storage &storage, int ai_family = AF_INET,
  254. int ai_socktype = SOCK_STREAM, int ai_protocol = IPPROTO_TCP, int expire_sec = 60) {
  255. try {
  256. storage = SockUtil::make_sockaddr(host, 0);
  257. return true;
  258. } catch (...) {
  259. auto item = getCacheDomainIP(host, expire_sec);
  260. if (!item) {
  261. item = getSystemDomainIP(host);
  262. if (item) {
  263. setCacheDomainIP(host, item);
  264. }
  265. }
  266. if (item) {
  267. auto addr = getPerferredAddress(item.get(), ai_family, ai_socktype, ai_protocol);
  268. memcpy(&storage, addr->ai_addr, addr->ai_addrlen);
  269. }
  270. return (bool)item;
  271. }
  272. }
  273. private:
  274. class DnsItem {
  275. public:
  276. std::shared_ptr<struct addrinfo> addr_info;
  277. time_t create_time;
  278. };
  279. std::shared_ptr<struct addrinfo> getCacheDomainIP(const char *host, int expireSec) {
  280. lock_guard<mutex> lck(_mtx);
  281. auto it = _dns_cache.find(host);
  282. if (it == _dns_cache.end()) {
  283. //没有记录
  284. return nullptr;
  285. }
  286. if (it->second.create_time + expireSec < time(nullptr)) {
  287. //已过期
  288. _dns_cache.erase(it);
  289. return nullptr;
  290. }
  291. return it->second.addr_info;
  292. }
  293. void setCacheDomainIP(const char *host, std::shared_ptr<struct addrinfo> addr) {
  294. lock_guard<mutex> lck(_mtx);
  295. DnsItem item;
  296. item.addr_info = std::move(addr);
  297. item.create_time = time(nullptr);
  298. _dns_cache[host] = std::move(item);
  299. }
  300. std::shared_ptr<struct addrinfo> getSystemDomainIP(const char *host) {
  301. struct addrinfo *answer = nullptr;
  302. //阻塞式dns解析,可能被打断
  303. int ret = -1;
  304. do {
  305. ret = getaddrinfo(host, nullptr, nullptr, &answer);
  306. } while (ret == -1 && get_uv_error(true) == UV_EINTR);
  307. if (!answer) {
  308. WarnL << "getaddrinfo failed: " << host;
  309. return nullptr;
  310. }
  311. return std::shared_ptr<struct addrinfo>(answer, freeaddrinfo);
  312. }
  313. struct addrinfo *getPerferredAddress(struct addrinfo *answer, int ai_family, int ai_socktype, int ai_protocol) {
  314. auto ptr = answer;
  315. while (ptr) {
  316. if (ptr->ai_family == ai_family && ptr->ai_socktype == ai_socktype && ptr->ai_protocol == ai_protocol) {
  317. return ptr;
  318. }
  319. ptr = ptr->ai_next;
  320. }
  321. return answer;
  322. }
  323. private:
  324. mutex _mtx;
  325. unordered_map<string, DnsItem> _dns_cache;
  326. };
  327. bool SockUtil::getDomainIP(const char *host, uint16_t port, struct sockaddr_storage &addr,
  328. int ai_family, int ai_socktype, int ai_protocol, int expire_sec) {
  329. bool flag = DnsCache::Instance().getDomainIP(host, addr, ai_family, ai_socktype, ai_protocol, expire_sec);
  330. if (flag) {
  331. switch (addr.ss_family ) {
  332. case AF_INET : ((sockaddr_in *) &addr)->sin_port = htons(port); break;
  333. case AF_INET6 : ((sockaddr_in6 *) &addr)->sin6_port = htons(port); break;
  334. default: assert(0); break;
  335. }
  336. }
  337. return flag;
  338. }
  339. static int set_ipv6_only(int fd, bool flag) {
  340. int opt = flag;
  341. int ret = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, sizeof opt);
  342. if (ret == -1) {
  343. TraceL << "setsockopt IPV6_V6ONLY failed";
  344. }
  345. return ret;
  346. }
  347. static int bind_sock6(int fd, const char *ifr_ip, uint16_t port) {
  348. set_ipv6_only(fd, false);
  349. struct sockaddr_in6 addr;
  350. bzero(&addr, sizeof(addr));
  351. addr.sin6_family = AF_INET6;
  352. addr.sin6_port = htons(port);
  353. if (1 != inet_pton(AF_INET6, ifr_ip, &(addr.sin6_addr))) {
  354. if (strcmp(ifr_ip, "0.0.0.0")) {
  355. WarnL << "inet_pton to ipv6 address failed: " << ifr_ip;
  356. }
  357. addr.sin6_addr = IN6ADDR_ANY_INIT;
  358. }
  359. if (::bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
  360. WarnL << "Bind socket failed: " << get_uv_errmsg(true);
  361. return -1;
  362. }
  363. return 0;
  364. }
  365. static int bind_sock4(int fd, const char *ifr_ip, uint16_t port) {
  366. struct sockaddr_in addr;
  367. bzero(&addr, sizeof(addr));
  368. addr.sin_family = AF_INET;
  369. addr.sin_port = htons(port);
  370. if (1 != inet_pton(AF_INET, ifr_ip, &(addr.sin_addr))) {
  371. if (strcmp(ifr_ip, "::")) {
  372. WarnL << "inet_pton to ipv4 address failed: " << ifr_ip;
  373. }
  374. addr.sin_addr.s_addr = INADDR_ANY;
  375. }
  376. if (::bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
  377. WarnL << "Bind socket failed: " << get_uv_errmsg(true);
  378. return -1;
  379. }
  380. return 0;
  381. }
  382. static int bind_sock(int fd, const char *ifr_ip, uint16_t port, int family) {
  383. switch (family) {
  384. case AF_INET: return bind_sock4(fd, ifr_ip, port);
  385. case AF_INET6: return bind_sock6(fd, ifr_ip, port);
  386. default: assert(0); return -1;
  387. }
  388. }
  389. int SockUtil::connect(const char *host, uint16_t port, bool async, const char *local_ip, uint16_t local_port) {
  390. sockaddr_storage addr;
  391. //优先使用ipv4地址
  392. if (!getDomainIP(host, port, addr, AF_INET, SOCK_STREAM, IPPROTO_TCP)) {
  393. //dns解析失败
  394. return -1;
  395. }
  396. int sockfd = (int) socket(addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
  397. if (sockfd < 0) {
  398. WarnL << "Create socket failed: " << host;
  399. return -1;
  400. }
  401. setReuseable(sockfd);
  402. setNoSigpipe(sockfd);
  403. setNoBlocked(sockfd, async);
  404. setNoDelay(sockfd);
  405. setSendBuf(sockfd);
  406. setRecvBuf(sockfd);
  407. setCloseWait(sockfd);
  408. setCloExec(sockfd);
  409. if (bind_sock(sockfd, local_ip, local_port, addr.ss_family) == -1) {
  410. close(sockfd);
  411. return -1;
  412. }
  413. if (::connect(sockfd, (sockaddr *) &addr, get_sock_len((sockaddr *)&addr)) == 0) {
  414. //同步连接成功
  415. return sockfd;
  416. }
  417. if (async && get_uv_error(true) == UV_EAGAIN) {
  418. //异步连接成功
  419. return sockfd;
  420. }
  421. WarnL << "Connect socket to " << host << " " << port << " failed: " << get_uv_errmsg(true);
  422. close(sockfd);
  423. return -1;
  424. }
  425. int SockUtil::listen(const uint16_t port, const char *local_ip, int back_log) {
  426. int fd = -1;
  427. int family = support_ipv6() ? (is_ipv4(local_ip) ? AF_INET : AF_INET6) : AF_INET;
  428. if ((fd = (int)socket(family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
  429. WarnL << "Create socket failed: " << get_uv_errmsg(true);
  430. return -1;
  431. }
  432. setReuseable(fd, true, false);
  433. setNoBlocked(fd);
  434. setCloExec(fd);
  435. if (bind_sock(fd, local_ip, port, family) == -1) {
  436. close(fd);
  437. return -1;
  438. }
  439. //开始监听
  440. if (::listen(fd, back_log) == -1) {
  441. WarnL << "Listen socket failed: " << get_uv_errmsg(true);
  442. close(fd);
  443. return -1;
  444. }
  445. return fd;
  446. }
  447. int SockUtil::getSockError(int fd) {
  448. int opt;
  449. socklen_t optLen = static_cast<socklen_t>(sizeof(opt));
  450. if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *) &opt, &optLen) < 0) {
  451. return get_uv_error(true);
  452. } else {
  453. return uv_translate_posix_error(opt);
  454. }
  455. }
  456. using getsockname_type = decltype(getsockname);
  457. static bool get_socket_addr(int fd, struct sockaddr_storage &addr, getsockname_type func) {
  458. socklen_t addr_len = sizeof(addr);
  459. if (-1 == func(fd, (struct sockaddr *)&addr, &addr_len)) {
  460. return false;
  461. }
  462. return true;
  463. }
  464. bool SockUtil::get_sock_local_addr(int fd, struct sockaddr_storage &addr) {
  465. return get_socket_addr(fd, addr, getsockname);
  466. }
  467. bool SockUtil::get_sock_peer_addr(int fd, struct sockaddr_storage &addr) {
  468. return get_socket_addr(fd, addr, getpeername);
  469. }
  470. static string get_socket_ip(int fd, getsockname_type func) {
  471. struct sockaddr_storage addr;
  472. if (!get_socket_addr(fd, addr, func)) {
  473. return "";
  474. }
  475. return SockUtil::inet_ntoa((struct sockaddr *)&addr);
  476. }
  477. static uint16_t get_socket_port(int fd, getsockname_type func) {
  478. struct sockaddr_storage addr;
  479. if (!get_socket_addr(fd, addr, func)) {
  480. return 0;
  481. }
  482. return SockUtil::inet_port((struct sockaddr *)&addr);
  483. }
  484. string SockUtil::get_local_ip(int fd) {
  485. return get_socket_ip(fd, getsockname);
  486. }
  487. string SockUtil::get_peer_ip(int fd) {
  488. return get_socket_ip(fd, getpeername);
  489. }
  490. uint16_t SockUtil::get_local_port(int fd) {
  491. return get_socket_port(fd, getsockname);
  492. }
  493. uint16_t SockUtil::get_peer_port(int fd) {
  494. return get_socket_port(fd, getpeername);
  495. }
  496. #if defined(__APPLE__)
  497. template<typename FUN>
  498. void for_each_netAdapter_apple(FUN &&fun) { //type: struct ifaddrs *
  499. struct ifaddrs *interfaces = nullptr;
  500. struct ifaddrs *adapter = nullptr;
  501. if (getifaddrs(&interfaces) == 0) {
  502. adapter = interfaces;
  503. while (adapter) {
  504. if (adapter->ifa_addr->sa_family == AF_INET) {
  505. if (fun(adapter)) {
  506. break;
  507. }
  508. }
  509. adapter = adapter->ifa_next;
  510. }
  511. freeifaddrs(interfaces);
  512. }
  513. }
  514. #endif //defined(__APPLE__)
  515. #if defined(_WIN32)
  516. template<typename FUN>
  517. void for_each_netAdapter_win32(FUN && fun) { //type: PIP_ADAPTER_INFO
  518. unsigned long nSize = sizeof(IP_ADAPTER_INFO);
  519. PIP_ADAPTER_INFO adapterList = (PIP_ADAPTER_INFO)new char[nSize];
  520. int nRet = GetAdaptersInfo(adapterList, &nSize);
  521. if (ERROR_BUFFER_OVERFLOW == nRet) {
  522. delete[] adapterList;
  523. adapterList = (PIP_ADAPTER_INFO)new char[nSize];
  524. nRet = GetAdaptersInfo(adapterList, &nSize);
  525. }
  526. auto adapterPtr = adapterList;
  527. while (adapterPtr && ERROR_SUCCESS == nRet) {
  528. if (fun(adapterPtr)) {
  529. break;
  530. }
  531. adapterPtr = adapterPtr->Next;
  532. }
  533. //释放内存空间
  534. delete[] adapterList;
  535. }
  536. #endif //defined(_WIN32)
  537. #if !defined(_WIN32) && !defined(__APPLE__)
  538. template<typename FUN>
  539. void for_each_netAdapter_posix(FUN &&fun){ //type: struct ifreq *
  540. struct ifconf ifconf;
  541. char buf[1024 * 10];
  542. //初始化ifconf
  543. ifconf.ifc_len = sizeof(buf);
  544. ifconf.ifc_buf = buf;
  545. int sockfd = ::socket(AF_INET, SOCK_DGRAM, 0);
  546. if (sockfd < 0) {
  547. WarnL << "Create socket failed: " << get_uv_errmsg(true);
  548. return;
  549. }
  550. if (-1 == ioctl(sockfd, SIOCGIFCONF, &ifconf)) { //获取所有接口信息
  551. WarnL << "ioctl SIOCGIFCONF failed: " << get_uv_errmsg(true);
  552. close(sockfd);
  553. return;
  554. }
  555. close(sockfd);
  556. //接下来一个一个的获取IP地址
  557. struct ifreq * adapter = (struct ifreq*) buf;
  558. for (int i = (ifconf.ifc_len / sizeof(struct ifreq)); i > 0; --i,++adapter) {
  559. if(fun(adapter)){
  560. break;
  561. }
  562. }
  563. }
  564. #endif //!defined(_WIN32) && !defined(__APPLE__)
  565. bool check_ip(string &address, const string &ip) {
  566. if (ip != "127.0.0.1" && ip != "0.0.0.0") {
  567. /*获取一个有效IP*/
  568. address = ip;
  569. uint32_t addressInNetworkOrder = htonl(inet_addr(ip.data()));
  570. if (/*(addressInNetworkOrder >= 0x0A000000 && addressInNetworkOrder < 0x0E000000) ||*/
  571. (addressInNetworkOrder >= 0xAC100000 && addressInNetworkOrder < 0xAC200000) ||
  572. (addressInNetworkOrder >= 0xC0A80000 && addressInNetworkOrder < 0xC0A90000)) {
  573. //A类私有IP地址:
  574. //10.0.0.0~10.255.255.255
  575. //B类私有IP地址:
  576. //172.16.0.0~172.31.255.255
  577. //C类私有IP地址:
  578. //192.168.0.0~192.168.255.255
  579. //如果是私有地址 说明在nat内部
  580. /* 优先采用局域网地址,该地址很可能是wifi地址
  581. * 一般来说,无线路由器分配的地址段是BC类私有ip地址
  582. * 而A类地址多用于蜂窝移动网络
  583. */
  584. return true;
  585. }
  586. }
  587. return false;
  588. }
  589. string SockUtil::get_local_ip() {
  590. #if defined(__APPLE__)
  591. string address = "127.0.0.1";
  592. for_each_netAdapter_apple([&](struct ifaddrs *adapter) {
  593. string ip = SockUtil::inet_ntoa(adapter->ifa_addr);
  594. if (strstr(adapter->ifa_name, "docker")) {
  595. return false;
  596. }
  597. return check_ip(address, ip);
  598. });
  599. return address;
  600. #elif defined(_WIN32)
  601. string address = "127.0.0.1";
  602. for_each_netAdapter_win32([&](PIP_ADAPTER_INFO adapter) {
  603. IP_ADDR_STRING *ipAddr = &(adapter->IpAddressList);
  604. while (ipAddr) {
  605. string ip = ipAddr->IpAddress.String;
  606. if (strstr(adapter->AdapterName, "docker")) {
  607. return false;
  608. }
  609. if(check_ip(address,ip)){
  610. return true;
  611. }
  612. ipAddr = ipAddr->Next;
  613. }
  614. return false;
  615. });
  616. return address;
  617. #else
  618. string address = "127.0.0.1";
  619. for_each_netAdapter_posix([&](struct ifreq *adapter){
  620. string ip = SockUtil::inet_ntoa(&(adapter->ifr_addr));
  621. if (strstr(adapter->ifr_name, "docker")) {
  622. return false;
  623. }
  624. return check_ip(address,ip);
  625. });
  626. return address;
  627. #endif
  628. }
  629. vector<map<string, string> > SockUtil::getInterfaceList() {
  630. vector<map<string, string> > ret;
  631. #if defined(__APPLE__)
  632. for_each_netAdapter_apple([&](struct ifaddrs *adapter) {
  633. map<string, string> obj;
  634. obj["ip"] = SockUtil::inet_ntoa(adapter->ifa_addr);
  635. obj["name"] = adapter->ifa_name;
  636. ret.emplace_back(std::move(obj));
  637. return false;
  638. });
  639. #elif defined(_WIN32)
  640. for_each_netAdapter_win32([&](PIP_ADAPTER_INFO adapter) {
  641. IP_ADDR_STRING *ipAddr = &(adapter->IpAddressList);
  642. while (ipAddr) {
  643. map<string,string> obj;
  644. obj["ip"] = ipAddr->IpAddress.String;
  645. obj["name"] = adapter->AdapterName;
  646. ret.emplace_back(std::move(obj));
  647. ipAddr = ipAddr->Next;
  648. }
  649. return false;
  650. });
  651. #else
  652. for_each_netAdapter_posix([&](struct ifreq *adapter){
  653. map<string,string> obj;
  654. obj["ip"] = SockUtil::inet_ntoa(&(adapter->ifr_addr));
  655. obj["name"] = adapter->ifr_name;
  656. ret.emplace_back(std::move(obj));
  657. return false;
  658. });
  659. #endif
  660. return ret;
  661. }
  662. int SockUtil::bindUdpSock(const uint16_t port, const char *local_ip, bool enable_reuse) {
  663. int fd = -1;
  664. int family = support_ipv6() ? (is_ipv4(local_ip) ? AF_INET : AF_INET6) : AF_INET;
  665. if ((fd = (int)socket(family, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
  666. WarnL << "Create socket failed: " << get_uv_errmsg(true);
  667. return -1;
  668. }
  669. if (enable_reuse) {
  670. setReuseable(fd);
  671. }
  672. setNoSigpipe(fd);
  673. setNoBlocked(fd);
  674. setSendBuf(fd);
  675. setRecvBuf(fd);
  676. setCloseWait(fd);
  677. setCloExec(fd);
  678. if (bind_sock(fd, local_ip, port, family) == -1) {
  679. close(fd);
  680. return -1;
  681. }
  682. return fd;
  683. }
  684. int SockUtil::dissolveUdpSock(int fd) {
  685. struct sockaddr_storage addr;
  686. socklen_t addr_len = sizeof(addr);
  687. if (-1 == getsockname(fd, (struct sockaddr *)&addr, &addr_len)) {
  688. return -1;
  689. }
  690. addr.ss_family = AF_UNSPEC;
  691. if (-1 == ::connect(fd, (struct sockaddr *)&addr, addr_len) && get_uv_error() != UV_EAFNOSUPPORT) {
  692. // mac/ios时返回EAFNOSUPPORT错误
  693. WarnL << "Connect socket AF_UNSPEC failed: " << get_uv_errmsg(true);
  694. return -1;
  695. }
  696. return 0;
  697. }
  698. string SockUtil::get_ifr_ip(const char *if_name) {
  699. #if defined(__APPLE__)
  700. string ret;
  701. for_each_netAdapter_apple([&](struct ifaddrs *adapter) {
  702. if (strcmp(adapter->ifa_name, if_name) == 0) {
  703. ret = SockUtil::inet_ntoa(adapter->ifa_addr);
  704. return true;
  705. }
  706. return false;
  707. });
  708. return ret;
  709. #elif defined(_WIN32)
  710. string ret;
  711. for_each_netAdapter_win32([&](PIP_ADAPTER_INFO adapter) {
  712. IP_ADDR_STRING *ipAddr = &(adapter->IpAddressList);
  713. while (ipAddr){
  714. if (strcmp(if_name,adapter->AdapterName) == 0){
  715. //ip匹配到了
  716. ret.assign(ipAddr->IpAddress.String);
  717. return true;
  718. }
  719. ipAddr = ipAddr->Next;
  720. }
  721. return false;
  722. });
  723. return ret;
  724. #else
  725. string ret;
  726. for_each_netAdapter_posix([&](struct ifreq *adapter){
  727. if(strcmp(adapter->ifr_name,if_name) == 0) {
  728. ret = SockUtil::inet_ntoa(&(adapter->ifr_addr));
  729. return true;
  730. }
  731. return false;
  732. });
  733. return ret;
  734. #endif
  735. }
  736. string SockUtil::get_ifr_name(const char *local_ip) {
  737. #if defined(__APPLE__)
  738. string ret = "en0";
  739. for_each_netAdapter_apple([&](struct ifaddrs *adapter) {
  740. string ip = SockUtil::inet_ntoa(adapter->ifa_addr);
  741. if (ip == local_ip) {
  742. ret = adapter->ifa_name;
  743. return true;
  744. }
  745. return false;
  746. });
  747. return ret;
  748. #elif defined(_WIN32)
  749. string ret = "en0";
  750. for_each_netAdapter_win32([&](PIP_ADAPTER_INFO adapter) {
  751. IP_ADDR_STRING *ipAddr = &(adapter->IpAddressList);
  752. while (ipAddr){
  753. if (strcmp(local_ip,ipAddr->IpAddress.String) == 0){
  754. //ip匹配到了
  755. ret.assign(adapter->AdapterName);
  756. return true;
  757. }
  758. ipAddr = ipAddr->Next;
  759. }
  760. return false;
  761. });
  762. return ret;
  763. #else
  764. string ret = "en0";
  765. for_each_netAdapter_posix([&](struct ifreq *adapter){
  766. string ip = SockUtil::inet_ntoa(&(adapter->ifr_addr));
  767. if(ip == local_ip) {
  768. ret = adapter->ifr_name;
  769. return true;
  770. }
  771. return false;
  772. });
  773. return ret;
  774. #endif
  775. }
  776. string SockUtil::get_ifr_mask(const char *if_name) {
  777. #if defined(__APPLE__)
  778. string ret;
  779. for_each_netAdapter_apple([&](struct ifaddrs *adapter) {
  780. if (strcmp(if_name, adapter->ifa_name) == 0) {
  781. ret = SockUtil::inet_ntoa(adapter->ifa_netmask);
  782. return true;
  783. }
  784. return false;
  785. });
  786. return ret;
  787. #elif defined(_WIN32)
  788. string ret;
  789. for_each_netAdapter_win32([&](PIP_ADAPTER_INFO adapter) {
  790. if (strcmp(if_name,adapter->AdapterName) == 0){
  791. //找到了该网卡
  792. IP_ADDR_STRING *ipAddr = &(adapter->IpAddressList);
  793. //获取第一个ip的子网掩码
  794. ret.assign(ipAddr->IpMask.String);
  795. return true;
  796. }
  797. return false;
  798. });
  799. return ret;
  800. #else
  801. int fd;
  802. struct ifreq ifr_mask;
  803. fd = socket(AF_INET, SOCK_STREAM, 0);
  804. if (fd == -1) {
  805. WarnL << "Create socket failed: " << get_uv_errmsg(true);
  806. return "";
  807. }
  808. memset(&ifr_mask, 0, sizeof(ifr_mask));
  809. strncpy(ifr_mask.ifr_name, if_name, sizeof(ifr_mask.ifr_name) - 1);
  810. if ((ioctl(fd, SIOCGIFNETMASK, &ifr_mask)) < 0) {
  811. WarnL << "ioctl SIOCGIFNETMASK on " << if_name << " failed: " << get_uv_errmsg(true);
  812. close(fd);
  813. return "";
  814. }
  815. close(fd);
  816. return SockUtil::inet_ntoa(&(ifr_mask.ifr_netmask));
  817. #endif // defined(_WIN32)
  818. }
  819. string SockUtil::get_ifr_brdaddr(const char *if_name) {
  820. #if defined(__APPLE__)
  821. string ret;
  822. for_each_netAdapter_apple([&](struct ifaddrs *adapter) {
  823. if (strcmp(if_name, adapter->ifa_name) == 0) {
  824. ret = SockUtil::inet_ntoa(adapter->ifa_broadaddr);
  825. return true;
  826. }
  827. return false;
  828. });
  829. return ret;
  830. #elif defined(_WIN32)
  831. string ret;
  832. for_each_netAdapter_win32([&](PIP_ADAPTER_INFO adapter) {
  833. if (strcmp(if_name, adapter->AdapterName) == 0) {
  834. //找到该网卡
  835. IP_ADDR_STRING *ipAddr = &(adapter->IpAddressList);
  836. in_addr broadcast;
  837. broadcast.S_un.S_addr = (inet_addr(ipAddr->IpAddress.String) & inet_addr(ipAddr->IpMask.String)) | (~inet_addr(ipAddr->IpMask.String));
  838. ret = SockUtil::inet_ntoa(broadcast);
  839. return true;
  840. }
  841. return false;
  842. });
  843. return ret;
  844. #else
  845. int fd;
  846. struct ifreq ifr_mask;
  847. fd = socket( AF_INET, SOCK_STREAM, 0);
  848. if (fd == -1) {
  849. WarnL << "Create socket failed: " << get_uv_errmsg(true);
  850. return "";
  851. }
  852. memset(&ifr_mask, 0, sizeof(ifr_mask));
  853. strncpy(ifr_mask.ifr_name, if_name, sizeof(ifr_mask.ifr_name) - 1);
  854. if ((ioctl(fd, SIOCGIFBRDADDR, &ifr_mask)) < 0) {
  855. WarnL << "ioctl SIOCGIFBRDADDR failed: " << get_uv_errmsg(true);
  856. close(fd);
  857. return "";
  858. }
  859. close(fd);
  860. return SockUtil::inet_ntoa(&(ifr_mask.ifr_broadaddr));
  861. #endif
  862. }
  863. #define ip_addr_netcmp(addr1, addr2, mask) (((addr1) & (mask)) == ((addr2) & (mask)))
  864. bool SockUtil::in_same_lan(const char *myIp, const char *dstIp) {
  865. string mask = get_ifr_mask(get_ifr_name(myIp).data());
  866. return ip_addr_netcmp(inet_addr(myIp), inet_addr(dstIp), inet_addr(mask.data()));
  867. }
  868. static void clearMulticastAllSocketOption(int socket) {
  869. #if defined(IP_MULTICAST_ALL)
  870. // This option is defined in modern versions of Linux to overcome a bug in the Linux kernel's default behavior.
  871. // When set to 0, it ensures that we receive only packets that were sent to the specified IP multicast address,
  872. // even if some other process on the same system has joined a different multicast group with the same port number.
  873. int multicastAll = 0;
  874. (void)setsockopt(socket, IPPROTO_IP, IP_MULTICAST_ALL, (void*)&multicastAll, sizeof multicastAll);
  875. // Ignore the call's result. Should it fail, we'll still receive packets (just perhaps more than intended)
  876. #endif
  877. }
  878. int SockUtil::setMultiTTL(int fd, uint8_t ttl) {
  879. int ret = -1;
  880. #if defined(IP_MULTICAST_TTL)
  881. ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &ttl, sizeof(ttl));
  882. if (ret == -1) {
  883. TraceL << "setsockopt IP_MULTICAST_TTL failed";
  884. }
  885. #endif
  886. clearMulticastAllSocketOption(fd);
  887. return ret;
  888. }
  889. int SockUtil::setMultiIF(int fd, const char *local_ip) {
  890. int ret = -1;
  891. #if defined(IP_MULTICAST_IF)
  892. struct in_addr addr;
  893. addr.s_addr = inet_addr(local_ip);
  894. ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &addr, sizeof(addr));
  895. if (ret == -1) {
  896. TraceL << "setsockopt IP_MULTICAST_IF failed";
  897. }
  898. #endif
  899. clearMulticastAllSocketOption(fd);
  900. return ret;
  901. }
  902. int SockUtil::setMultiLOOP(int fd, bool accept) {
  903. int ret = -1;
  904. #if defined(IP_MULTICAST_LOOP)
  905. uint8_t loop = accept;
  906. ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &loop, sizeof(loop));
  907. if (ret == -1) {
  908. TraceL << "setsockopt IP_MULTICAST_LOOP failed";
  909. }
  910. #endif
  911. clearMulticastAllSocketOption(fd);
  912. return ret;
  913. }
  914. int SockUtil::joinMultiAddr(int fd, const char *addr, const char *local_ip) {
  915. int ret = -1;
  916. #if defined(IP_ADD_MEMBERSHIP)
  917. struct ip_mreq imr;
  918. imr.imr_multiaddr.s_addr = inet_addr(addr);
  919. imr.imr_interface.s_addr = inet_addr(local_ip);
  920. ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq));
  921. if (ret == -1) {
  922. TraceL << "setsockopt IP_ADD_MEMBERSHIP failed: " << get_uv_errmsg(true);
  923. }
  924. #endif
  925. clearMulticastAllSocketOption(fd);
  926. return ret;
  927. }
  928. int SockUtil::leaveMultiAddr(int fd, const char *addr, const char *local_ip) {
  929. int ret = -1;
  930. #if defined(IP_DROP_MEMBERSHIP)
  931. struct ip_mreq imr;
  932. imr.imr_multiaddr.s_addr = inet_addr(addr);
  933. imr.imr_interface.s_addr = inet_addr(local_ip);
  934. ret = setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq));
  935. if (ret == -1) {
  936. TraceL << "setsockopt IP_DROP_MEMBERSHIP failed: " << get_uv_errmsg(true);
  937. }
  938. #endif
  939. clearMulticastAllSocketOption(fd);
  940. return ret;
  941. }
  942. template<typename A, typename B>
  943. static inline void write4Byte(A &&a, B &&b) {
  944. memcpy(&a, &b, sizeof(a));
  945. }
  946. int SockUtil::joinMultiAddrFilter(int fd, const char *addr, const char *src_ip, const char *local_ip) {
  947. int ret = -1;
  948. #if defined(IP_ADD_SOURCE_MEMBERSHIP)
  949. struct ip_mreq_source imr;
  950. write4Byte(imr.imr_multiaddr, inet_addr(addr));
  951. write4Byte(imr.imr_sourceaddr, inet_addr(src_ip));
  952. write4Byte(imr.imr_interface, inet_addr(local_ip));
  953. ret = setsockopt(fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq_source));
  954. if (ret == -1) {
  955. TraceL << "setsockopt IP_ADD_SOURCE_MEMBERSHIP failed: " << get_uv_errmsg(true);
  956. }
  957. #endif
  958. clearMulticastAllSocketOption(fd);
  959. return ret;
  960. }
  961. int SockUtil::leaveMultiAddrFilter(int fd, const char *addr, const char *src_ip, const char *local_ip) {
  962. int ret = -1;
  963. #if defined(IP_DROP_SOURCE_MEMBERSHIP)
  964. struct ip_mreq_source imr;
  965. write4Byte(imr.imr_multiaddr, inet_addr(addr));
  966. write4Byte(imr.imr_sourceaddr, inet_addr(src_ip));
  967. write4Byte(imr.imr_interface, inet_addr(local_ip));
  968. ret = setsockopt(fd, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq_source));
  969. if (ret == -1) {
  970. TraceL << "setsockopt IP_DROP_SOURCE_MEMBERSHIP failed: " << get_uv_errmsg(true);
  971. }
  972. #endif
  973. clearMulticastAllSocketOption(fd);
  974. return ret;
  975. }
  976. bool SockUtil::is_ipv4(const char *host) {
  977. struct in_addr addr;
  978. return 1 == inet_pton(AF_INET, host, &addr);
  979. }
  980. bool SockUtil::is_ipv6(const char *host) {
  981. struct in6_addr addr;
  982. return 1 == inet_pton(AF_INET6, host, &addr);
  983. }
  984. socklen_t SockUtil::get_sock_len(const struct sockaddr *addr) {
  985. switch (addr->sa_family) {
  986. case AF_INET : return sizeof(sockaddr_in);
  987. case AF_INET6 : return sizeof(sockaddr_in6);
  988. default: assert(0); return 0;
  989. }
  990. }
  991. struct sockaddr_storage SockUtil::make_sockaddr(const char *host, uint16_t port) {
  992. struct sockaddr_storage storage;
  993. bzero(&storage, sizeof(storage));
  994. struct in_addr addr;
  995. struct in6_addr addr6;
  996. if (1 == inet_pton(AF_INET, host, &addr)) {
  997. // host是ipv4
  998. reinterpret_cast<struct sockaddr_in &>(storage).sin_addr = addr;
  999. reinterpret_cast<struct sockaddr_in &>(storage).sin_family = AF_INET;
  1000. reinterpret_cast<struct sockaddr_in &>(storage).sin_port = htons(port);
  1001. return storage;
  1002. }
  1003. if (1 == inet_pton(AF_INET6, host, &addr6)) {
  1004. // host是ipv6
  1005. reinterpret_cast<struct sockaddr_in6 &>(storage).sin6_addr = addr6;
  1006. reinterpret_cast<struct sockaddr_in6 &>(storage).sin6_family = AF_INET6;
  1007. reinterpret_cast<struct sockaddr_in6 &>(storage).sin6_port = htons(port);
  1008. return storage;
  1009. }
  1010. throw std::invalid_argument(string("Not ip address: ") + host);
  1011. }
  1012. } // namespace toolkit