1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to 8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the 9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions: 12d4afb5ceSopenharmony_ci * 13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in 14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software. 15d4afb5ceSopenharmony_ci * 16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22d4afb5ceSopenharmony_ci * IN THE SOFTWARE. 23d4afb5ceSopenharmony_ci */ 24d4afb5ceSopenharmony_ci 25d4afb5ceSopenharmony_ci#include "private-lib-core.h" 26d4afb5ceSopenharmony_ci#include <errno.h> 27d4afb5ceSopenharmony_ci#if defined(LWS_WITH_MBEDTLS) 28d4afb5ceSopenharmony_ci#if defined(LWS_HAVE_MBEDTLS_NET_SOCKETS) 29d4afb5ceSopenharmony_ci#include "mbedtls/net_sockets.h" 30d4afb5ceSopenharmony_ci#else 31d4afb5ceSopenharmony_ci#include "mbedtls/net.h" 32d4afb5ceSopenharmony_ci#endif 33d4afb5ceSopenharmony_ci#endif 34d4afb5ceSopenharmony_ci 35d4afb5ceSopenharmony_ciint 36d4afb5ceSopenharmony_cilws_send_pipe_choked(struct lws *wsi) 37d4afb5ceSopenharmony_ci{ 38d4afb5ceSopenharmony_ci struct lws *wsi_eff = wsi; 39d4afb5ceSopenharmony_ci fd_set writefds; 40d4afb5ceSopenharmony_ci struct timeval tv = { 0, 0 }; 41d4afb5ceSopenharmony_ci int n; 42d4afb5ceSopenharmony_ci#if defined(LWS_WITH_HTTP2) 43d4afb5ceSopenharmony_ci wsi_eff = lws_get_network_wsi(wsi); 44d4afb5ceSopenharmony_ci#endif 45d4afb5ceSopenharmony_ci 46d4afb5ceSopenharmony_ci /* the fact we checked implies we avoided back-to-back writes */ 47d4afb5ceSopenharmony_ci wsi_eff->could_have_pending = 0; 48d4afb5ceSopenharmony_ci 49d4afb5ceSopenharmony_ci /* treat the fact we got a truncated send pending as if we're choked */ 50d4afb5ceSopenharmony_ci if (lws_has_buffered_out(wsi) 51d4afb5ceSopenharmony_ci#if defined(LWS_WITH_HTTP_STREAM_COMPRESSION) 52d4afb5ceSopenharmony_ci || wsi->http.comp_ctx.buflist_comp || 53d4afb5ceSopenharmony_ci wsi->http.comp_ctx.may_have_more 54d4afb5ceSopenharmony_ci#endif 55d4afb5ceSopenharmony_ci ) 56d4afb5ceSopenharmony_ci return 1; 57d4afb5ceSopenharmony_ci 58d4afb5ceSopenharmony_ci FD_ZERO(&writefds); 59d4afb5ceSopenharmony_ci FD_SET(wsi_eff->desc.sockfd, &writefds); 60d4afb5ceSopenharmony_ci 61d4afb5ceSopenharmony_ci n = select(wsi_eff->desc.sockfd + 1, NULL, &writefds, NULL, &tv); 62d4afb5ceSopenharmony_ci if (n < 0) 63d4afb5ceSopenharmony_ci return 1; /* choked */ 64d4afb5ceSopenharmony_ci 65d4afb5ceSopenharmony_ci return !n; /* n = 0 = not writable = choked */ 66d4afb5ceSopenharmony_ci} 67d4afb5ceSopenharmony_ci 68d4afb5ceSopenharmony_ciint 69d4afb5ceSopenharmony_cilws_poll_listen_fd(struct lws_pollfd *fd) 70d4afb5ceSopenharmony_ci{ 71d4afb5ceSopenharmony_ci fd_set readfds; 72d4afb5ceSopenharmony_ci struct timeval tv = { 0, 0 }; 73d4afb5ceSopenharmony_ci 74d4afb5ceSopenharmony_ci FD_ZERO(&readfds); 75d4afb5ceSopenharmony_ci FD_SET(fd->fd, &readfds); 76d4afb5ceSopenharmony_ci 77d4afb5ceSopenharmony_ci return select(fd->fd + 1, &readfds, NULL, NULL, &tv); 78d4afb5ceSopenharmony_ci} 79d4afb5ceSopenharmony_ci 80d4afb5ceSopenharmony_ciint 81d4afb5ceSopenharmony_cilws_plat_set_nonblocking(lws_sockfd_type fd) 82d4afb5ceSopenharmony_ci{ 83d4afb5ceSopenharmony_ci return fcntl(fd, F_SETFL, O_NONBLOCK) < 0; 84d4afb5ceSopenharmony_ci} 85d4afb5ceSopenharmony_ci 86d4afb5ceSopenharmony_ciint 87d4afb5ceSopenharmony_cilws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt) 88d4afb5ceSopenharmony_ci{ 89d4afb5ceSopenharmony_ci int optval = 1; 90d4afb5ceSopenharmony_ci socklen_t optlen = sizeof(optval); 91d4afb5ceSopenharmony_ci 92d4afb5ceSopenharmony_ci#if defined(__APPLE__) || \ 93d4afb5ceSopenharmony_ci defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \ 94d4afb5ceSopenharmony_ci defined(__NetBSD__) || \ 95d4afb5ceSopenharmony_ci defined(__OpenBSD__) 96d4afb5ceSopenharmony_ci struct protoent *tcp_proto; 97d4afb5ceSopenharmony_ci#endif 98d4afb5ceSopenharmony_ci 99d4afb5ceSopenharmony_ci if (vhost->ka_time) { 100d4afb5ceSopenharmony_ci /* enable keepalive on this socket */ 101d4afb5ceSopenharmony_ci optval = 1; 102d4afb5ceSopenharmony_ci if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, 103d4afb5ceSopenharmony_ci (const void *)&optval, optlen) < 0) 104d4afb5ceSopenharmony_ci return 1; 105d4afb5ceSopenharmony_ci 106d4afb5ceSopenharmony_ci#if defined(__APPLE__) || \ 107d4afb5ceSopenharmony_ci defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \ 108d4afb5ceSopenharmony_ci defined(__NetBSD__) || \ 109d4afb5ceSopenharmony_ci defined(__CYGWIN__) || defined(__OpenBSD__) || defined (__sun) 110d4afb5ceSopenharmony_ci 111d4afb5ceSopenharmony_ci /* 112d4afb5ceSopenharmony_ci * didn't find a way to set these per-socket, need to 113d4afb5ceSopenharmony_ci * tune kernel systemwide values 114d4afb5ceSopenharmony_ci */ 115d4afb5ceSopenharmony_ci#else 116d4afb5ceSopenharmony_ci /* set the keepalive conditions we want on it too */ 117d4afb5ceSopenharmony_ci optval = vhost->ka_time; 118d4afb5ceSopenharmony_ci if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, 119d4afb5ceSopenharmony_ci (const void *)&optval, optlen) < 0) 120d4afb5ceSopenharmony_ci return 1; 121d4afb5ceSopenharmony_ci 122d4afb5ceSopenharmony_ci optval = vhost->ka_interval; 123d4afb5ceSopenharmony_ci if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, 124d4afb5ceSopenharmony_ci (const void *)&optval, optlen) < 0) 125d4afb5ceSopenharmony_ci return 1; 126d4afb5ceSopenharmony_ci 127d4afb5ceSopenharmony_ci optval = vhost->ka_probes; 128d4afb5ceSopenharmony_ci if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, 129d4afb5ceSopenharmony_ci (const void *)&optval, optlen) < 0) 130d4afb5ceSopenharmony_ci return 1; 131d4afb5ceSopenharmony_ci#endif 132d4afb5ceSopenharmony_ci } 133d4afb5ceSopenharmony_ci 134d4afb5ceSopenharmony_ci /* Disable Nagle */ 135d4afb5ceSopenharmony_ci optval = 1; 136d4afb5ceSopenharmony_ci if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, optlen) < 0) 137d4afb5ceSopenharmony_ci return 1; 138d4afb5ceSopenharmony_ci 139d4afb5ceSopenharmony_ci return lws_plat_set_nonblocking(fd); 140d4afb5ceSopenharmony_ci} 141d4afb5ceSopenharmony_ci 142d4afb5ceSopenharmony_cistatic const int ip_opt_lws_flags[] = { 143d4afb5ceSopenharmony_ci LCCSCF_IP_LOW_LATENCY, LCCSCF_IP_HIGH_THROUGHPUT, 144d4afb5ceSopenharmony_ci LCCSCF_IP_HIGH_RELIABILITY, LCCSCF_IP_LOW_COST 145d4afb5ceSopenharmony_ci}, ip_opt_val[] = { 146d4afb5ceSopenharmony_ci IPTOS_LOWDELAY, IPTOS_THROUGHPUT, IPTOS_RELIABILITY, IPTOS_MINCOST 147d4afb5ceSopenharmony_ci}; 148d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_NO_LOGS) 149d4afb5ceSopenharmony_cistatic const char *ip_opt_names[] = { 150d4afb5ceSopenharmony_ci "LOWDELAY", "THROUGHPUT", "RELIABILITY", "MINCOST" 151d4afb5ceSopenharmony_ci}; 152d4afb5ceSopenharmony_ci#endif 153d4afb5ceSopenharmony_ci 154d4afb5ceSopenharmony_ciint 155d4afb5ceSopenharmony_cilws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags) 156d4afb5ceSopenharmony_ci{ 157d4afb5ceSopenharmony_ci int optval = (int)pri, ret = 0, n; 158d4afb5ceSopenharmony_ci socklen_t optlen = sizeof(optval); 159d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_NO_LOGS) 160d4afb5ceSopenharmony_ci int en; 161d4afb5ceSopenharmony_ci#endif 162d4afb5ceSopenharmony_ci 163d4afb5ceSopenharmony_ci#if defined(SO_PRIORITY) 164d4afb5ceSopenharmony_ci if (pri) { /* 0 is the default already */ 165d4afb5ceSopenharmony_ci if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, 166d4afb5ceSopenharmony_ci (const void *)&optval, optlen) < 0) { 167d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_NO_LOGS) 168d4afb5ceSopenharmony_ci en = errno; 169d4afb5ceSopenharmony_ci lwsl_warn("%s: unable to set socket pri %d: errno %d\n", 170d4afb5ceSopenharmony_ci __func__, (int)pri, en); 171d4afb5ceSopenharmony_ci#endif 172d4afb5ceSopenharmony_ci ret = 1; 173d4afb5ceSopenharmony_ci } else 174d4afb5ceSopenharmony_ci lwsl_notice("%s: set pri %u\n", __func__, pri); 175d4afb5ceSopenharmony_ci } 176d4afb5ceSopenharmony_ci#endif 177d4afb5ceSopenharmony_ci 178d4afb5ceSopenharmony_ci for (n = 0; n < 4; n++) { 179d4afb5ceSopenharmony_ci if (!(lws_flags & ip_opt_lws_flags[n])) 180d4afb5ceSopenharmony_ci continue; 181d4afb5ceSopenharmony_ci 182d4afb5ceSopenharmony_ci optval = (int)ip_opt_val[n]; 183d4afb5ceSopenharmony_ci if (setsockopt(fd, IPPROTO_IP, IP_TOS, (const void *)&optval, 184d4afb5ceSopenharmony_ci optlen) < 0) { 185d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_NO_LOGS) 186d4afb5ceSopenharmony_ci en = errno; 187d4afb5ceSopenharmony_ci lwsl_warn("%s: unable to set %s: errno %d\n", __func__, 188d4afb5ceSopenharmony_ci ip_opt_names[n], en); 189d4afb5ceSopenharmony_ci#endif 190d4afb5ceSopenharmony_ci ret = 1; 191d4afb5ceSopenharmony_ci } else 192d4afb5ceSopenharmony_ci lwsl_notice("%s: set ip flag %s\n", __func__, 193d4afb5ceSopenharmony_ci ip_opt_names[n]); 194d4afb5ceSopenharmony_ci } 195d4afb5ceSopenharmony_ci 196d4afb5ceSopenharmony_ci return ret; 197d4afb5ceSopenharmony_ci} 198d4afb5ceSopenharmony_ci 199d4afb5ceSopenharmony_ci/* cast a struct sockaddr_in6 * into addr for ipv6 */ 200d4afb5ceSopenharmony_ci 201d4afb5ceSopenharmony_ciint 202d4afb5ceSopenharmony_cilws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr, 203d4afb5ceSopenharmony_ci size_t addrlen) 204d4afb5ceSopenharmony_ci{ 205d4afb5ceSopenharmony_ci#if 0 206d4afb5ceSopenharmony_ci int rc = LWS_ITOSA_NOT_EXIST; 207d4afb5ceSopenharmony_ci 208d4afb5ceSopenharmony_ci struct ifaddrs *ifr; 209d4afb5ceSopenharmony_ci struct ifaddrs *ifc; 210d4afb5ceSopenharmony_ci#ifdef LWS_WITH_IPV6 211d4afb5ceSopenharmony_ci struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; 212d4afb5ceSopenharmony_ci#endif 213d4afb5ceSopenharmony_ci 214d4afb5ceSopenharmony_ci getifaddrs(&ifr); 215d4afb5ceSopenharmony_ci for (ifc = ifr; ifc != NULL && rc; ifc = ifc->ifa_next) { 216d4afb5ceSopenharmony_ci if (!ifc->ifa_addr) 217d4afb5ceSopenharmony_ci continue; 218d4afb5ceSopenharmony_ci 219d4afb5ceSopenharmony_ci lwsl_info(" interface %s vs %s\n", ifc->ifa_name, ifname); 220d4afb5ceSopenharmony_ci 221d4afb5ceSopenharmony_ci if (strcmp(ifc->ifa_name, ifname)) 222d4afb5ceSopenharmony_ci continue; 223d4afb5ceSopenharmony_ci 224d4afb5ceSopenharmony_ci switch (ifc->ifa_addr->sa_family) { 225d4afb5ceSopenharmony_ci case AF_INET: 226d4afb5ceSopenharmony_ci#ifdef LWS_WITH_IPV6 227d4afb5ceSopenharmony_ci if (ipv6) { 228d4afb5ceSopenharmony_ci /* map IPv4 to IPv6 */ 229d4afb5ceSopenharmony_ci memset((char *)&addr6->sin6_addr, 0, 230d4afb5ceSopenharmony_ci sizeof(struct in6_addr)); 231d4afb5ceSopenharmony_ci addr6->sin6_addr.s6_addr[10] = 0xff; 232d4afb5ceSopenharmony_ci addr6->sin6_addr.s6_addr[11] = 0xff; 233d4afb5ceSopenharmony_ci memcpy(&addr6->sin6_addr.s6_addr[12], 234d4afb5ceSopenharmony_ci &((struct sockaddr_in *)ifc->ifa_addr)->sin_addr, 235d4afb5ceSopenharmony_ci sizeof(struct in_addr)); 236d4afb5ceSopenharmony_ci } else 237d4afb5ceSopenharmony_ci#endif 238d4afb5ceSopenharmony_ci memcpy(addr, 239d4afb5ceSopenharmony_ci (struct sockaddr_in *)ifc->ifa_addr, 240d4afb5ceSopenharmony_ci sizeof(struct sockaddr_in)); 241d4afb5ceSopenharmony_ci break; 242d4afb5ceSopenharmony_ci#ifdef LWS_WITH_IPV6 243d4afb5ceSopenharmony_ci case AF_INET6: 244d4afb5ceSopenharmony_ci memcpy(&addr6->sin6_addr, 245d4afb5ceSopenharmony_ci &((struct sockaddr_in6 *)ifc->ifa_addr)->sin6_addr, 246d4afb5ceSopenharmony_ci sizeof(struct in6_addr)); 247d4afb5ceSopenharmony_ci break; 248d4afb5ceSopenharmony_ci#endif 249d4afb5ceSopenharmony_ci default: 250d4afb5ceSopenharmony_ci continue; 251d4afb5ceSopenharmony_ci } 252d4afb5ceSopenharmony_ci rc = LWS_ITOSA_USABLE; 253d4afb5ceSopenharmony_ci } 254d4afb5ceSopenharmony_ci 255d4afb5ceSopenharmony_ci freeifaddrs(ifr); 256d4afb5ceSopenharmony_ci 257d4afb5ceSopenharmony_ci if (rc == LWS_ITOSA_NOT_EXIST) { 258d4afb5ceSopenharmony_ci /* check if bind to IP address */ 259d4afb5ceSopenharmony_ci#ifdef LWS_WITH_IPV6 260d4afb5ceSopenharmony_ci if (inet_pton(AF_INET6, ifname, &addr6->sin6_addr) == 1) 261d4afb5ceSopenharmony_ci rc = LWS_ITOSA_USABLE; 262d4afb5ceSopenharmony_ci else 263d4afb5ceSopenharmony_ci#endif 264d4afb5ceSopenharmony_ci if (inet_pton(AF_INET, ifname, &addr->sin_addr) == 1) 265d4afb5ceSopenharmony_ci rc = LWS_ITOSA_USABLE; 266d4afb5ceSopenharmony_ci } 267d4afb5ceSopenharmony_ci 268d4afb5ceSopenharmony_ci return rc; 269d4afb5ceSopenharmony_ci#endif 270d4afb5ceSopenharmony_ci 271d4afb5ceSopenharmony_ci return LWS_ITOSA_NOT_EXIST; 272d4afb5ceSopenharmony_ci} 273d4afb5ceSopenharmony_ci 274d4afb5ceSopenharmony_ciconst char * 275d4afb5ceSopenharmony_cilws_plat_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) 276d4afb5ceSopenharmony_ci{ 277d4afb5ceSopenharmony_ci return inet_ntop(af, src, dst, cnt); 278d4afb5ceSopenharmony_ci} 279d4afb5ceSopenharmony_ci 280d4afb5ceSopenharmony_ciint 281d4afb5ceSopenharmony_cilws_plat_inet_pton(int af, const char *src, void *dst) 282d4afb5ceSopenharmony_ci{ 283d4afb5ceSopenharmony_ci return 1; // inet_pton(af, src, dst); 284d4afb5ceSopenharmony_ci} 285d4afb5ceSopenharmony_ci 286d4afb5ceSopenharmony_ciint 287d4afb5ceSopenharmony_cilws_plat_ifname_to_hwaddr(int fd, const char *ifname, uint8_t *hwaddr, int len) 288d4afb5ceSopenharmony_ci{ 289d4afb5ceSopenharmony_ci lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__); 290d4afb5ceSopenharmony_ci 291d4afb5ceSopenharmony_ci return -1; 292d4afb5ceSopenharmony_ci} 293d4afb5ceSopenharmony_ci 294d4afb5ceSopenharmony_ciint 295d4afb5ceSopenharmony_cilws_plat_rawudp_broadcast(uint8_t *p, const uint8_t *canned, size_t canned_len, 296d4afb5ceSopenharmony_ci size_t n, int fd, const char *iface) 297d4afb5ceSopenharmony_ci{ 298d4afb5ceSopenharmony_ci lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__); 299d4afb5ceSopenharmony_ci 300d4afb5ceSopenharmony_ci return -1; 301d4afb5ceSopenharmony_ci} 302d4afb5ceSopenharmony_ci 303d4afb5ceSopenharmony_ciint 304d4afb5ceSopenharmony_cilws_plat_if_up(const char *ifname, int fd, int up) 305d4afb5ceSopenharmony_ci{ 306d4afb5ceSopenharmony_ci lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__); 307d4afb5ceSopenharmony_ci 308d4afb5ceSopenharmony_ci return -1; 309d4afb5ceSopenharmony_ci} 310d4afb5ceSopenharmony_ci 311d4afb5ceSopenharmony_ciint 312d4afb5ceSopenharmony_cilws_plat_BINDTODEVICE(lws_sockfd_type fd, const char *ifname) 313d4afb5ceSopenharmony_ci{ 314d4afb5ceSopenharmony_ci lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__); 315d4afb5ceSopenharmony_ci 316d4afb5ceSopenharmony_ci return -1; 317d4afb5ceSopenharmony_ci} 318d4afb5ceSopenharmony_ci 319d4afb5ceSopenharmony_ciint 320d4afb5ceSopenharmony_cilws_plat_ifconfig(int fd, lws_dhcpc_ifstate_t *is) 321d4afb5ceSopenharmony_ci{ 322d4afb5ceSopenharmony_ci lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__); 323d4afb5ceSopenharmony_ci 324d4afb5ceSopenharmony_ci return -1; 325d4afb5ceSopenharmony_ci} 326d4afb5ceSopenharmony_ci 327d4afb5ceSopenharmony_ciint 328d4afb5ceSopenharmony_cilws_plat_vhost_tls_client_ctx_init(struct lws_vhost *vhost) 329d4afb5ceSopenharmony_ci{ 330d4afb5ceSopenharmony_ci return 0; 331d4afb5ceSopenharmony_ci} 332d4afb5ceSopenharmony_ci 333d4afb5ceSopenharmony_ci#if defined(LWS_WITH_MBEDTLS) 334d4afb5ceSopenharmony_ciint 335d4afb5ceSopenharmony_cilws_plat_mbedtls_net_send(void *ctx, const uint8_t *buf, size_t len) 336d4afb5ceSopenharmony_ci{ 337d4afb5ceSopenharmony_ci int fd = ((mbedtls_net_context *) ctx)->fd; 338d4afb5ceSopenharmony_ci int ret; 339d4afb5ceSopenharmony_ci 340d4afb5ceSopenharmony_ci if (fd < 0) 341d4afb5ceSopenharmony_ci return MBEDTLS_ERR_NET_INVALID_CONTEXT; 342d4afb5ceSopenharmony_ci 343d4afb5ceSopenharmony_ci ret = write(fd, buf, len); 344d4afb5ceSopenharmony_ci if (ret >= 0) 345d4afb5ceSopenharmony_ci return ret; 346d4afb5ceSopenharmony_ci 347d4afb5ceSopenharmony_ci if (errno == EAGAIN || errno == EWOULDBLOCK) 348d4afb5ceSopenharmony_ci return MBEDTLS_ERR_SSL_WANT_WRITE; 349d4afb5ceSopenharmony_ci 350d4afb5ceSopenharmony_ci if (errno == EPIPE || errno == ECONNRESET) 351d4afb5ceSopenharmony_ci return MBEDTLS_ERR_NET_CONN_RESET; 352d4afb5ceSopenharmony_ci 353d4afb5ceSopenharmony_ci if( errno == EINTR ) 354d4afb5ceSopenharmony_ci return MBEDTLS_ERR_SSL_WANT_WRITE; 355d4afb5ceSopenharmony_ci 356d4afb5ceSopenharmony_ci return MBEDTLS_ERR_NET_SEND_FAILED; 357d4afb5ceSopenharmony_ci} 358d4afb5ceSopenharmony_ci 359d4afb5ceSopenharmony_ciint 360d4afb5ceSopenharmony_cilws_plat_mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len) 361d4afb5ceSopenharmony_ci{ 362d4afb5ceSopenharmony_ci int fd = ((mbedtls_net_context *) ctx)->fd; 363d4afb5ceSopenharmony_ci int ret; 364d4afb5ceSopenharmony_ci 365d4afb5ceSopenharmony_ci if (fd < 0) 366d4afb5ceSopenharmony_ci return MBEDTLS_ERR_NET_INVALID_CONTEXT; 367d4afb5ceSopenharmony_ci 368d4afb5ceSopenharmony_ci ret = (int)read(fd, buf, len); 369d4afb5ceSopenharmony_ci if (ret >= 0) 370d4afb5ceSopenharmony_ci return ret; 371d4afb5ceSopenharmony_ci 372d4afb5ceSopenharmony_ci if (errno == EAGAIN || errno == EWOULDBLOCK) 373d4afb5ceSopenharmony_ci return MBEDTLS_ERR_SSL_WANT_READ; 374d4afb5ceSopenharmony_ci 375d4afb5ceSopenharmony_ci if (errno == EPIPE || errno == ECONNRESET) 376d4afb5ceSopenharmony_ci return MBEDTLS_ERR_NET_CONN_RESET; 377d4afb5ceSopenharmony_ci 378d4afb5ceSopenharmony_ci if (errno == EINTR || !errno) 379d4afb5ceSopenharmony_ci return MBEDTLS_ERR_SSL_WANT_READ; 380d4afb5ceSopenharmony_ci 381d4afb5ceSopenharmony_ci return MBEDTLS_ERR_NET_RECV_FAILED; 382d4afb5ceSopenharmony_ci} 383d4afb5ceSopenharmony_ci#endif 384d4afb5ceSopenharmony_ci 385