unix-sockets.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to
  8. * deal in the Software without restriction, including without limitation the
  9. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. * sell copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. * IN THE SOFTWARE.
  23. */
  24. #if !defined(_GNU_SOURCE)
  25. #define _GNU_SOURCE
  26. #endif
  27. #include "private-lib-core.h"
  28. #include <sys/ioctl.h>
  29. #if !defined(LWS_DETECTED_PLAT_IOS)
  30. #include <net/route.h>
  31. #endif
  32. #include <net/if.h>
  33. #include <pwd.h>
  34. #include <grp.h>
  35. #if defined(LWS_WITH_MBEDTLS)
  36. #if defined(LWS_HAVE_MBEDTLS_NET_SOCKETS)
  37. #include "mbedtls/net_sockets.h"
  38. #else
  39. #include "mbedtls/net.h"
  40. #endif
  41. #endif
  42. int
  43. lws_send_pipe_choked(struct lws *wsi)
  44. {
  45. struct lws_pollfd fds;
  46. struct lws *wsi_eff;
  47. #if !defined(LWS_WITHOUT_EXTENSIONS)
  48. if (wsi->ws && wsi->ws->tx_draining_ext)
  49. return 1;
  50. #endif
  51. #if defined(LWS_WITH_HTTP2)
  52. wsi_eff = lws_get_network_wsi(wsi);
  53. #else
  54. wsi_eff = wsi;
  55. #endif
  56. /* the fact we checked implies we avoided back-to-back writes */
  57. wsi_eff->could_have_pending = 0;
  58. /* treat the fact we got a truncated send pending as if we're choked */
  59. if (lws_has_buffered_out(wsi_eff)
  60. #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
  61. ||wsi->http.comp_ctx.buflist_comp ||
  62. wsi->http.comp_ctx.may_have_more
  63. #endif
  64. )
  65. return 1;
  66. fds.fd = wsi_eff->desc.sockfd;
  67. fds.events = POLLOUT;
  68. fds.revents = 0;
  69. if (poll(&fds, 1, 0) != 1)
  70. return 1;
  71. if ((fds.revents & POLLOUT) == 0)
  72. return 1;
  73. /* okay to send another packet without blocking */
  74. return 0;
  75. }
  76. int
  77. lws_plat_set_nonblocking(lws_sockfd_type fd)
  78. {
  79. return fcntl(fd, F_SETFL, O_NONBLOCK) < 0;
  80. }
  81. int
  82. lws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt)
  83. {
  84. int optval = 1;
  85. socklen_t optlen = sizeof(optval);
  86. #if defined(__APPLE__) || \
  87. defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
  88. defined(__NetBSD__) || \
  89. defined(__OpenBSD__) || \
  90. defined(__HAIKU__)
  91. struct protoent *tcp_proto;
  92. #endif
  93. (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
  94. if (!unix_skt && vhost->ka_time) {
  95. /* enable keepalive on this socket */
  96. optval = 1;
  97. if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
  98. (const void *)&optval, optlen) < 0)
  99. return 1;
  100. #if defined(__APPLE__) || \
  101. defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
  102. defined(__NetBSD__) || \
  103. defined(__CYGWIN__) || defined(__OpenBSD__) || defined (__sun) || \
  104. defined(__HAIKU__)
  105. /*
  106. * didn't find a way to set these per-socket, need to
  107. * tune kernel systemwide values
  108. */
  109. #else
  110. /* set the keepalive conditions we want on it too */
  111. #if defined(LWS_HAVE_TCP_USER_TIMEOUT)
  112. optval = 1000 * (vhost->ka_time +
  113. (vhost->ka_interval * vhost->ka_probes));
  114. if (setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT,
  115. (const void *)&optval, optlen) < 0)
  116. return 1;
  117. #endif
  118. optval = vhost->ka_time;
  119. if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE,
  120. (const void *)&optval, optlen) < 0)
  121. return 1;
  122. optval = vhost->ka_interval;
  123. if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL,
  124. (const void *)&optval, optlen) < 0)
  125. return 1;
  126. optval = vhost->ka_probes;
  127. if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT,
  128. (const void *)&optval, optlen) < 0)
  129. return 1;
  130. #endif
  131. }
  132. #if defined(SO_BINDTODEVICE)
  133. if (!unix_skt && vhost->bind_iface && vhost->iface) {
  134. lwsl_info("binding listen skt to %s using SO_BINDTODEVICE\n", vhost->iface);
  135. if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, vhost->iface,
  136. strlen(vhost->iface)) < 0) {
  137. lwsl_warn("Failed to bind to device %s\n", vhost->iface);
  138. return 1;
  139. }
  140. }
  141. #endif
  142. /* Disable Nagle */
  143. optval = 1;
  144. #if defined (__sun) || defined(__QNX__)
  145. if (!unix_skt && setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void *)&optval, optlen) < 0)
  146. return 1;
  147. #elif !defined(__APPLE__) && \
  148. !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) && \
  149. !defined(__NetBSD__) && \
  150. !defined(__OpenBSD__) && \
  151. !defined(__HAIKU__)
  152. if (!unix_skt && setsockopt(fd, SOL_TCP, TCP_NODELAY, (const void *)&optval, optlen) < 0)
  153. return 1;
  154. #else
  155. tcp_proto = getprotobyname("TCP");
  156. if (!unix_skt && setsockopt(fd, tcp_proto->p_proto, TCP_NODELAY, &optval, optlen) < 0)
  157. return 1;
  158. #endif
  159. return lws_plat_set_nonblocking(fd);
  160. }
  161. /* cast a struct sockaddr_in6 * into addr for ipv6 */
  162. int
  163. lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
  164. size_t addrlen)
  165. {
  166. int rc = LWS_ITOSA_NOT_EXIST;
  167. struct ifaddrs *ifr;
  168. struct ifaddrs *ifc;
  169. #ifdef LWS_WITH_IPV6
  170. struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
  171. #endif
  172. if (getifaddrs(&ifr)) {
  173. lwsl_err("%s: unable to getifaddrs: errno %d\n", __func__, errno);
  174. return LWS_ITOSA_USABLE;
  175. }
  176. for (ifc = ifr; ifc != NULL && rc; ifc = ifc->ifa_next) {
  177. if (!ifc->ifa_addr || !ifc->ifa_name)
  178. continue;
  179. lwsl_debug(" interface %s vs %s (fam %d) ipv6 %d\n",
  180. ifc->ifa_name, ifname,
  181. ifc->ifa_addr->sa_family, ipv6);
  182. if (strcmp(ifc->ifa_name, ifname))
  183. continue;
  184. switch (ifc->ifa_addr->sa_family) {
  185. #if defined(AF_PACKET)
  186. case AF_PACKET:
  187. /* interface exists but is not usable */
  188. rc = LWS_ITOSA_NOT_USABLE;
  189. continue;
  190. #endif
  191. case AF_INET:
  192. #ifdef LWS_WITH_IPV6
  193. if (ipv6) {
  194. /* map IPv4 to IPv6 */
  195. memset((char *)&addr6->sin6_addr, 0,
  196. sizeof(struct in6_addr));
  197. addr6->sin6_addr.s6_addr[10] = 0xff;
  198. addr6->sin6_addr.s6_addr[11] = 0xff;
  199. memcpy(&addr6->sin6_addr.s6_addr[12],
  200. &((struct sockaddr_in *)ifc->ifa_addr)->sin_addr,
  201. sizeof(struct in_addr));
  202. lwsl_debug("%s: uplevelling ipv4 bind to ipv6\n", __func__);
  203. } else
  204. #endif
  205. memcpy(addr,
  206. (struct sockaddr_in *)ifc->ifa_addr,
  207. sizeof(struct sockaddr_in));
  208. break;
  209. #ifdef LWS_WITH_IPV6
  210. case AF_INET6:
  211. memcpy(&addr6->sin6_addr,
  212. &((struct sockaddr_in6 *)ifc->ifa_addr)->sin6_addr,
  213. sizeof(struct in6_addr));
  214. break;
  215. #endif
  216. default:
  217. continue;
  218. }
  219. rc = LWS_ITOSA_USABLE;
  220. }
  221. freeifaddrs(ifr);
  222. if (rc) {
  223. /* check if bind to IP address */
  224. #ifdef LWS_WITH_IPV6
  225. if (inet_pton(AF_INET6, ifname, &addr6->sin6_addr) == 1)
  226. rc = LWS_ITOSA_USABLE;
  227. else
  228. #endif
  229. if (inet_pton(AF_INET, ifname, &addr->sin_addr) == 1)
  230. rc = LWS_ITOSA_USABLE;
  231. }
  232. return rc;
  233. }
  234. const char *
  235. lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
  236. {
  237. return inet_ntop(af, src, dst, cnt);
  238. }
  239. int
  240. lws_plat_inet_pton(int af, const char *src, void *dst)
  241. {
  242. return inet_pton(af, src, dst);
  243. }
  244. int
  245. lws_plat_ifname_to_hwaddr(int fd, const char *ifname, uint8_t *hwaddr, int len)
  246. {
  247. #if defined(__linux__)
  248. struct ifreq i;
  249. memset(&i, 0, sizeof(i));
  250. lws_strncpy(i.ifr_name, ifname, sizeof(i.ifr_name));
  251. if (ioctl(fd, SIOCGIFHWADDR, &i) < 0)
  252. return -1;
  253. memcpy(hwaddr, &i.ifr_hwaddr.sa_data, 6);
  254. return 6;
  255. #else
  256. lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
  257. return -1;
  258. #endif
  259. }
  260. int
  261. lws_plat_rawudp_broadcast(uint8_t *p, const uint8_t *canned, int canned_len,
  262. int n, int fd, const char *iface)
  263. {
  264. #if defined(__linux__)
  265. struct sockaddr_ll sll;
  266. uint16_t *p16 = (uint16_t *)p;
  267. uint32_t ucs = 0;
  268. memcpy(p, canned, canned_len);
  269. p[2] = n >> 8;
  270. p[3] = n;
  271. while (p16 < (uint16_t *)(p + 20))
  272. ucs += ntohs(*p16++);
  273. ucs += ucs >> 16;
  274. ucs ^= 0xffff;
  275. p[10] = ucs >> 8;
  276. p[11] = ucs;
  277. p[24] = (n - 20) >> 8;
  278. p[25] = (n - 20);
  279. memset(&sll, 0, sizeof(sll));
  280. sll.sll_family = AF_PACKET;
  281. sll.sll_protocol = htons(0x800);
  282. sll.sll_halen = 6;
  283. sll.sll_ifindex = if_nametoindex(iface);
  284. memset(sll.sll_addr, 0xff, 6);
  285. return sendto(fd, p, n, 0, (struct sockaddr *)&sll, sizeof(sll));
  286. #else
  287. lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
  288. return -1;
  289. #endif
  290. }
  291. int
  292. lws_plat_if_up(const char *ifname, int fd, int up)
  293. {
  294. #if defined(__linux__)
  295. struct ifreq ifr;
  296. memset(&ifr, 0, sizeof(ifr));
  297. lws_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
  298. if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
  299. lwsl_err("%s: SIOCGIFFLAGS fail\n", __func__);
  300. return 1;
  301. }
  302. if (up)
  303. ifr.ifr_flags |= IFF_UP;
  304. else
  305. ifr.ifr_flags &= ~IFF_UP;
  306. if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
  307. lwsl_err("%s: SIOCSIFFLAGS fail\n", __func__);
  308. return 1;
  309. }
  310. return 0;
  311. #else
  312. lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
  313. return -1;
  314. #endif
  315. }
  316. int
  317. lws_plat_BINDTODEVICE(lws_sockfd_type fd, const char *ifname)
  318. {
  319. #if defined(__linux__)
  320. struct ifreq i;
  321. memset(&i, 0, sizeof(i));
  322. i.ifr_addr.sa_family = AF_INET;
  323. lws_strncpy(i.ifr_ifrn.ifrn_name, ifname,
  324. sizeof(i.ifr_ifrn.ifrn_name));
  325. if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &i, sizeof(i)) < 0) {
  326. lwsl_notice("%s: failed %d\n", __func__, LWS_ERRNO);
  327. return 1;
  328. }
  329. return 0;
  330. #else
  331. lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
  332. return -1;
  333. #endif
  334. }
  335. int
  336. lws_plat_ifconfig_ip(const char *ifname, int fd, uint8_t *ip, uint8_t *mask_ip,
  337. uint8_t *gateway_ip)
  338. {
  339. #if defined(__linux__)
  340. struct sockaddr_in sin;
  341. struct rtentry route;
  342. struct ifreq ifr;
  343. memset(&ifr, 0, sizeof(ifr));
  344. memset(&route, 0, sizeof(route));
  345. memset(&sin, 0, sizeof(sin));
  346. lws_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
  347. lws_plat_if_up(ifname, fd, 0);
  348. sin.sin_family = AF_INET;
  349. sin.sin_addr.s_addr = htonl(*(uint32_t *)ip);
  350. memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
  351. if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) {
  352. lwsl_err("%s: SIOCSIFADDR fail\n", __func__);
  353. return 1;
  354. }
  355. sin.sin_addr.s_addr = htonl(*(uint32_t *)mask_ip);
  356. memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
  357. if (ioctl(fd, SIOCSIFNETMASK, &ifr) < 0) {
  358. lwsl_err("%s: SIOCSIFNETMASK fail\n", __func__);
  359. return 1;
  360. }
  361. lws_plat_if_up(ifname, fd, 1);
  362. sin.sin_addr.s_addr = htonl(*(uint32_t *)gateway_ip);
  363. memcpy(&route.rt_gateway, &sin, sizeof(struct sockaddr));
  364. sin.sin_addr.s_addr = 0;
  365. memcpy(&route.rt_dst, &sin, sizeof(struct sockaddr));
  366. memcpy(&route.rt_genmask, &sin, sizeof(struct sockaddr));
  367. route.rt_flags = RTF_UP | RTF_GATEWAY;
  368. route.rt_metric = 100;
  369. route.rt_dev = (char *)ifname;
  370. if (ioctl(fd, SIOCADDRT, &route) < 0) {
  371. lwsl_err("%s: SIOCADDRT 0x%x fail: %d\n", __func__,
  372. (unsigned int)htonl(*(uint32_t *)gateway_ip), LWS_ERRNO);
  373. return 1;
  374. }
  375. return 0;
  376. #else
  377. lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
  378. return -1;
  379. #endif
  380. }
  381. #if defined(LWS_WITH_MBEDTLS)
  382. int
  383. lws_plat_mbedtls_net_send(void *ctx, const uint8_t *buf, size_t len)
  384. {
  385. int fd = ((mbedtls_net_context *) ctx)->fd;
  386. int ret;
  387. if (fd < 0)
  388. return MBEDTLS_ERR_NET_INVALID_CONTEXT;
  389. ret = write(fd, buf, len);
  390. if (ret >= 0)
  391. return ret;
  392. if (errno == EAGAIN || errno == EWOULDBLOCK)
  393. return MBEDTLS_ERR_SSL_WANT_WRITE;
  394. if (errno == EPIPE || errno == ECONNRESET)
  395. return MBEDTLS_ERR_NET_CONN_RESET;
  396. if( errno == EINTR )
  397. return MBEDTLS_ERR_SSL_WANT_WRITE;
  398. return MBEDTLS_ERR_NET_SEND_FAILED;
  399. }
  400. int
  401. lws_plat_mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len)
  402. {
  403. int fd = ((mbedtls_net_context *) ctx)->fd;
  404. int ret;
  405. if (fd < 0)
  406. return MBEDTLS_ERR_NET_INVALID_CONTEXT;
  407. ret = (int)read(fd, buf, len);
  408. if (ret >= 0)
  409. return ret;
  410. if (errno == EAGAIN || errno == EWOULDBLOCK)
  411. return MBEDTLS_ERR_SSL_WANT_READ;
  412. if (errno == EPIPE || errno == ECONNRESET)
  413. return MBEDTLS_ERR_NET_CONN_RESET;
  414. if (errno == EINTR)
  415. return MBEDTLS_ERR_SSL_WANT_READ;
  416. return MBEDTLS_ERR_NET_RECV_FAILED;
  417. }
  418. #endif