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