xref: /aosp_15_r20/external/libwebsockets/lib/plat/windows/windows-sockets.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2010 - 2021 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  */
24*1c60b9acSAndroid Build Coastguard Worker 
25*1c60b9acSAndroid Build Coastguard Worker #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
26*1c60b9acSAndroid Build Coastguard Worker #define _WINSOCK_DEPRECATED_NO_WARNINGS
27*1c60b9acSAndroid Build Coastguard Worker #endif
28*1c60b9acSAndroid Build Coastguard Worker #define MBEDTLS_ALLOW_PRIVATE_ACCESS
29*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
30*1c60b9acSAndroid Build Coastguard Worker 
31*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_MBEDTLS)
32*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_MBEDTLS_NET_SOCKETS)
33*1c60b9acSAndroid Build Coastguard Worker #include "mbedtls/net_sockets.h"
34*1c60b9acSAndroid Build Coastguard Worker #else
35*1c60b9acSAndroid Build Coastguard Worker #include "mbedtls/net.h"
36*1c60b9acSAndroid Build Coastguard Worker #endif
37*1c60b9acSAndroid Build Coastguard Worker #endif
38*1c60b9acSAndroid Build Coastguard Worker 
39*1c60b9acSAndroid Build Coastguard Worker int
lws_send_pipe_choked(struct lws * wsi)40*1c60b9acSAndroid Build Coastguard Worker lws_send_pipe_choked(struct lws *wsi)
41*1c60b9acSAndroid Build Coastguard Worker {	struct lws *wsi_eff;
42*1c60b9acSAndroid Build Coastguard Worker 
43*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_HTTP2)
44*1c60b9acSAndroid Build Coastguard Worker 	wsi_eff = lws_get_network_wsi(wsi);
45*1c60b9acSAndroid Build Coastguard Worker #else
46*1c60b9acSAndroid Build Coastguard Worker 	wsi_eff = wsi;
47*1c60b9acSAndroid Build Coastguard Worker #endif
48*1c60b9acSAndroid Build Coastguard Worker 	/* the fact we checked implies we avoided back-to-back writes */
49*1c60b9acSAndroid Build Coastguard Worker 	wsi_eff->could_have_pending = 0;
50*1c60b9acSAndroid Build Coastguard Worker 
51*1c60b9acSAndroid Build Coastguard Worker 	/* treat the fact we got a truncated send pending as if we're choked */
52*1c60b9acSAndroid Build Coastguard Worker 	if (lws_has_buffered_out(wsi_eff)
53*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
54*1c60b9acSAndroid Build Coastguard Worker 	    ||wsi->http.comp_ctx.buflist_comp ||
55*1c60b9acSAndroid Build Coastguard Worker 	      wsi->http.comp_ctx.may_have_more
56*1c60b9acSAndroid Build Coastguard Worker #endif
57*1c60b9acSAndroid Build Coastguard Worker 	)
58*1c60b9acSAndroid Build Coastguard Worker 		return 1;
59*1c60b9acSAndroid Build Coastguard Worker 
60*1c60b9acSAndroid Build Coastguard Worker 	return (int)wsi_eff->sock_send_blocking;
61*1c60b9acSAndroid Build Coastguard Worker }
62*1c60b9acSAndroid Build Coastguard Worker 
63*1c60b9acSAndroid Build Coastguard Worker int
lws_poll_listen_fd(struct lws_pollfd * fd)64*1c60b9acSAndroid Build Coastguard Worker lws_poll_listen_fd(struct lws_pollfd *fd)
65*1c60b9acSAndroid Build Coastguard Worker {
66*1c60b9acSAndroid Build Coastguard Worker 	fd_set readfds;
67*1c60b9acSAndroid Build Coastguard Worker 	struct timeval tv = { 0, 0 };
68*1c60b9acSAndroid Build Coastguard Worker 
69*1c60b9acSAndroid Build Coastguard Worker 	assert((fd->events & LWS_POLLIN) == LWS_POLLIN);
70*1c60b9acSAndroid Build Coastguard Worker 
71*1c60b9acSAndroid Build Coastguard Worker 	FD_ZERO(&readfds);
72*1c60b9acSAndroid Build Coastguard Worker 	FD_SET(fd->fd, &readfds);
73*1c60b9acSAndroid Build Coastguard Worker 
74*1c60b9acSAndroid Build Coastguard Worker 	return select(((int)fd->fd) + 1, &readfds, NULL, NULL, &tv);
75*1c60b9acSAndroid Build Coastguard Worker }
76*1c60b9acSAndroid Build Coastguard Worker 
77*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_set_nonblocking(lws_sockfd_type fd)78*1c60b9acSAndroid Build Coastguard Worker lws_plat_set_nonblocking(lws_sockfd_type fd)
79*1c60b9acSAndroid Build Coastguard Worker {
80*1c60b9acSAndroid Build Coastguard Worker 	u_long optl = 1;
81*1c60b9acSAndroid Build Coastguard Worker 	int result = !!ioctlsocket(fd, FIONBIO, &optl);
82*1c60b9acSAndroid Build Coastguard Worker 	if (result)
83*1c60b9acSAndroid Build Coastguard Worker 	{
84*1c60b9acSAndroid Build Coastguard Worker 		int error = LWS_ERRNO;
85*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("ioctlsocket FIONBIO 1 failed with error %d\n", error);
86*1c60b9acSAndroid Build Coastguard Worker 	}
87*1c60b9acSAndroid Build Coastguard Worker 	return result;
88*1c60b9acSAndroid Build Coastguard Worker }
89*1c60b9acSAndroid Build Coastguard Worker 
90*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_set_socket_options(struct lws_vhost * vhost,lws_sockfd_type fd,int unix_skt)91*1c60b9acSAndroid Build Coastguard Worker lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd,
92*1c60b9acSAndroid Build Coastguard Worker 			    int unix_skt)
93*1c60b9acSAndroid Build Coastguard Worker {
94*1c60b9acSAndroid Build Coastguard Worker 	int optval = 1;
95*1c60b9acSAndroid Build Coastguard Worker 	int optlen = sizeof(optval);
96*1c60b9acSAndroid Build Coastguard Worker 	DWORD dwBytesRet;
97*1c60b9acSAndroid Build Coastguard Worker 	struct tcp_keepalive alive;
98*1c60b9acSAndroid Build Coastguard Worker 	int protonbr;
99*1c60b9acSAndroid Build Coastguard Worker #ifndef _WIN32_WCE
100*1c60b9acSAndroid Build Coastguard Worker 	struct protoent *tcp_proto;
101*1c60b9acSAndroid Build Coastguard Worker #endif
102*1c60b9acSAndroid Build Coastguard Worker 
103*1c60b9acSAndroid Build Coastguard Worker 	if (vhost->ka_time) {
104*1c60b9acSAndroid Build Coastguard Worker 		/* enable keepalive on this socket */
105*1c60b9acSAndroid Build Coastguard Worker 		optval = 1;
106*1c60b9acSAndroid Build Coastguard Worker 		if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
107*1c60b9acSAndroid Build Coastguard Worker 			       (const char *)&optval, optlen) < 0) {
108*1c60b9acSAndroid Build Coastguard Worker 			int error = LWS_ERRNO;
109*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("setsockopt SO_KEEPALIVE 1 failed with error %d\n", error);
110*1c60b9acSAndroid Build Coastguard Worker 			return 1;
111*1c60b9acSAndroid Build Coastguard Worker 		}
112*1c60b9acSAndroid Build Coastguard Worker 
113*1c60b9acSAndroid Build Coastguard Worker 		alive.onoff = TRUE;
114*1c60b9acSAndroid Build Coastguard Worker 		alive.keepalivetime = vhost->ka_time * 1000;
115*1c60b9acSAndroid Build Coastguard Worker 		alive.keepaliveinterval = vhost->ka_interval * 1000;
116*1c60b9acSAndroid Build Coastguard Worker 
117*1c60b9acSAndroid Build Coastguard Worker 		if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive),
118*1c60b9acSAndroid Build Coastguard Worker 			     NULL, 0, &dwBytesRet, NULL, NULL)) {
119*1c60b9acSAndroid Build Coastguard Worker 			int error = LWS_ERRNO;
120*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("WSAIoctl SIO_KEEPALIVE_VALS 1 %lu %lu failed with error %d\n", alive.keepalivetime, alive.keepaliveinterval, error);
121*1c60b9acSAndroid Build Coastguard Worker 			return 1;
122*1c60b9acSAndroid Build Coastguard Worker 		}
123*1c60b9acSAndroid Build Coastguard Worker 	}
124*1c60b9acSAndroid Build Coastguard Worker 
125*1c60b9acSAndroid Build Coastguard Worker 	/* Disable Nagle */
126*1c60b9acSAndroid Build Coastguard Worker 	optval = 1;
127*1c60b9acSAndroid Build Coastguard Worker #ifndef _WIN32_WCE
128*1c60b9acSAndroid Build Coastguard Worker 	tcp_proto = getprotobyname("TCP");
129*1c60b9acSAndroid Build Coastguard Worker 	if (!tcp_proto) {
130*1c60b9acSAndroid Build Coastguard Worker 		int error = LWS_ERRNO;
131*1c60b9acSAndroid Build Coastguard Worker 		lwsl_warn("getprotobyname(\"TCP\") failed with error, falling back to 6 %d\n", error);
132*1c60b9acSAndroid Build Coastguard Worker 		protonbr = 6;  /* IPPROTO_TCP */
133*1c60b9acSAndroid Build Coastguard Worker 	} else
134*1c60b9acSAndroid Build Coastguard Worker 		protonbr = tcp_proto->p_proto;
135*1c60b9acSAndroid Build Coastguard Worker #else
136*1c60b9acSAndroid Build Coastguard Worker 	protonbr = 6;
137*1c60b9acSAndroid Build Coastguard Worker #endif
138*1c60b9acSAndroid Build Coastguard Worker 
139*1c60b9acSAndroid Build Coastguard Worker 	if (setsockopt(fd, protonbr, TCP_NODELAY, (const char *)&optval, optlen) ) {
140*1c60b9acSAndroid Build Coastguard Worker 		int error = LWS_ERRNO;
141*1c60b9acSAndroid Build Coastguard Worker 		lwsl_warn("setsockopt TCP_NODELAY 1 failed with error %d\n", error);
142*1c60b9acSAndroid Build Coastguard Worker 	}
143*1c60b9acSAndroid Build Coastguard Worker 
144*1c60b9acSAndroid Build Coastguard Worker 	return lws_plat_set_nonblocking(fd);
145*1c60b9acSAndroid Build Coastguard Worker }
146*1c60b9acSAndroid Build Coastguard Worker 
147*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_set_socket_options_ip(lws_sockfd_type fd,uint8_t pri,int lws_flags)148*1c60b9acSAndroid Build Coastguard Worker lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags)
149*1c60b9acSAndroid Build Coastguard Worker {
150*1c60b9acSAndroid Build Coastguard Worker 	/*
151*1c60b9acSAndroid Build Coastguard Worker 	 * Seems to require "differeniated services" but no docs
152*1c60b9acSAndroid Build Coastguard Worker 	 *
153*1c60b9acSAndroid Build Coastguard Worker 	 * https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options
154*1c60b9acSAndroid Build Coastguard Worker 	 * https://docs.microsoft.com/en-us/previous-versions/windows/desktop/qos/differentiated-services
155*1c60b9acSAndroid Build Coastguard Worker 	 */
156*1c60b9acSAndroid Build Coastguard Worker 	lwsl_warn("%s: not implemented on windows platform\n", __func__);
157*1c60b9acSAndroid Build Coastguard Worker 
158*1c60b9acSAndroid Build Coastguard Worker 	return 0;
159*1c60b9acSAndroid Build Coastguard Worker }
160*1c60b9acSAndroid Build Coastguard Worker 
161*1c60b9acSAndroid Build Coastguard Worker int
lws_interface_to_sa(int ipv6,const char * ifname,struct sockaddr_in * addr,size_t addrlen)162*1c60b9acSAndroid Build Coastguard Worker lws_interface_to_sa(int ipv6,
163*1c60b9acSAndroid Build Coastguard Worker 		const char *ifname, struct sockaddr_in *addr, size_t addrlen)
164*1c60b9acSAndroid Build Coastguard Worker {
165*1c60b9acSAndroid Build Coastguard Worker 	long long address;
166*1c60b9acSAndroid Build Coastguard Worker #ifdef LWS_WITH_IPV6
167*1c60b9acSAndroid Build Coastguard Worker 	struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
168*1c60b9acSAndroid Build Coastguard Worker 
169*1c60b9acSAndroid Build Coastguard Worker 	if (ipv6) {
170*1c60b9acSAndroid Build Coastguard Worker 		if (lws_plat_inet_pton(AF_INET6, ifname, &addr6->sin6_addr) == 1) {
171*1c60b9acSAndroid Build Coastguard Worker 			return LWS_ITOSA_USABLE;
172*1c60b9acSAndroid Build Coastguard Worker 		}
173*1c60b9acSAndroid Build Coastguard Worker 	}
174*1c60b9acSAndroid Build Coastguard Worker #endif
175*1c60b9acSAndroid Build Coastguard Worker 
176*1c60b9acSAndroid Build Coastguard Worker 	address = inet_addr(ifname);
177*1c60b9acSAndroid Build Coastguard Worker 
178*1c60b9acSAndroid Build Coastguard Worker 	if (address == INADDR_NONE) {
179*1c60b9acSAndroid Build Coastguard Worker 		struct hostent *entry = gethostbyname(ifname);
180*1c60b9acSAndroid Build Coastguard Worker 		if (entry)
181*1c60b9acSAndroid Build Coastguard Worker 			address = ((struct in_addr *)entry->h_addr_list[0])->s_addr;
182*1c60b9acSAndroid Build Coastguard Worker 	}
183*1c60b9acSAndroid Build Coastguard Worker 
184*1c60b9acSAndroid Build Coastguard Worker 	if (address == INADDR_NONE)
185*1c60b9acSAndroid Build Coastguard Worker 		return LWS_ITOSA_NOT_EXIST;
186*1c60b9acSAndroid Build Coastguard Worker 
187*1c60b9acSAndroid Build Coastguard Worker 	addr->sin_addr.s_addr = (unsigned long)(lws_intptr_t)address;
188*1c60b9acSAndroid Build Coastguard Worker 
189*1c60b9acSAndroid Build Coastguard Worker 	return LWS_ITOSA_USABLE;
190*1c60b9acSAndroid Build Coastguard Worker }
191*1c60b9acSAndroid Build Coastguard Worker 
192*1c60b9acSAndroid Build Coastguard Worker void
lws_plat_insert_socket_into_fds(struct lws_context * context,struct lws * wsi)193*1c60b9acSAndroid Build Coastguard Worker lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
194*1c60b9acSAndroid Build Coastguard Worker {
195*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
196*1c60b9acSAndroid Build Coastguard Worker 
197*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_UDP)
198*1c60b9acSAndroid Build Coastguard Worker 	if (wsi->udp) {
199*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: UDP\n", __func__);
200*1c60b9acSAndroid Build Coastguard Worker 		pt->fds[pt->fds_count].events |= LWS_POLLIN;
201*1c60b9acSAndroid Build Coastguard Worker 	}
202*1c60b9acSAndroid Build Coastguard Worker #endif
203*1c60b9acSAndroid Build Coastguard Worker 
204*1c60b9acSAndroid Build Coastguard Worker 	if (context->event_loop_ops->io)
205*1c60b9acSAndroid Build Coastguard Worker 		context->event_loop_ops->io(wsi, LWS_EV_START | LWS_EV_READ);
206*1c60b9acSAndroid Build Coastguard Worker 
207*1c60b9acSAndroid Build Coastguard Worker 	pt->fds[pt->fds_count++].revents = 0;
208*1c60b9acSAndroid Build Coastguard Worker 
209*1c60b9acSAndroid Build Coastguard Worker 	lws_plat_change_pollfd(context, wsi, &pt->fds[pt->fds_count - 1]);
210*1c60b9acSAndroid Build Coastguard Worker }
211*1c60b9acSAndroid Build Coastguard Worker 
212*1c60b9acSAndroid Build Coastguard Worker void
lws_plat_delete_socket_from_fds(struct lws_context * context,struct lws * wsi,int m)213*1c60b9acSAndroid Build Coastguard Worker lws_plat_delete_socket_from_fds(struct lws_context *context,
214*1c60b9acSAndroid Build Coastguard Worker 						struct lws *wsi, int m)
215*1c60b9acSAndroid Build Coastguard Worker {
216*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
217*1c60b9acSAndroid Build Coastguard Worker 
218*1c60b9acSAndroid Build Coastguard Worker 	pt->fds_count--;
219*1c60b9acSAndroid Build Coastguard Worker }
220*1c60b9acSAndroid Build Coastguard Worker 
221*1c60b9acSAndroid Build Coastguard Worker 
222*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_check_connection_error(struct lws * wsi)223*1c60b9acSAndroid Build Coastguard Worker lws_plat_check_connection_error(struct lws *wsi)
224*1c60b9acSAndroid Build Coastguard Worker {
225*1c60b9acSAndroid Build Coastguard Worker 	int optVal;
226*1c60b9acSAndroid Build Coastguard Worker 	int optLen = sizeof(int);
227*1c60b9acSAndroid Build Coastguard Worker 
228*1c60b9acSAndroid Build Coastguard Worker 	if (getsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_ERROR,
229*1c60b9acSAndroid Build Coastguard Worker 			   (char*)&optVal, &optLen) != SOCKET_ERROR && optVal &&
230*1c60b9acSAndroid Build Coastguard Worker 		optVal != LWS_EALREADY && optVal != LWS_EINPROGRESS &&
231*1c60b9acSAndroid Build Coastguard Worker 		optVal != LWS_EWOULDBLOCK && optVal != WSAEINVAL) {
232*1c60b9acSAndroid Build Coastguard Worker 		   lwsl_debug("Connect failed SO_ERROR=%d\n", optVal);
233*1c60b9acSAndroid Build Coastguard Worker 		   return 1;
234*1c60b9acSAndroid Build Coastguard Worker 	}
235*1c60b9acSAndroid Build Coastguard Worker 
236*1c60b9acSAndroid Build Coastguard Worker 	return 0;
237*1c60b9acSAndroid Build Coastguard Worker }
238*1c60b9acSAndroid Build Coastguard Worker 
239*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_change_pollfd(struct lws_context * context,struct lws * wsi,struct lws_pollfd * pfd)240*1c60b9acSAndroid Build Coastguard Worker lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi,
241*1c60b9acSAndroid Build Coastguard Worker 		       struct lws_pollfd *pfd)
242*1c60b9acSAndroid Build Coastguard Worker {
243*1c60b9acSAndroid Build Coastguard Worker 	//struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
244*1c60b9acSAndroid Build Coastguard Worker 
245*1c60b9acSAndroid Build Coastguard Worker 	return 0;
246*1c60b9acSAndroid Build Coastguard Worker }
247*1c60b9acSAndroid Build Coastguard Worker 
248*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_TLS)
249*1c60b9acSAndroid Build Coastguard Worker 
250*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_vhost_tls_client_ctx_init(struct lws_vhost * vhost)251*1c60b9acSAndroid Build Coastguard Worker lws_plat_vhost_tls_client_ctx_init(struct lws_vhost *vhost)
252*1c60b9acSAndroid Build Coastguard Worker {
253*1c60b9acSAndroid Build Coastguard Worker #if !defined(LWS_WITH_MBEDTLS) && defined(LWS_SSL_CLIENT_USE_OS_CA_CERTS)
254*1c60b9acSAndroid Build Coastguard Worker 	PCCERT_CONTEXT pcc = NULL;
255*1c60b9acSAndroid Build Coastguard Worker 	CERT_ENHKEY_USAGE* ceu = NULL;
256*1c60b9acSAndroid Build Coastguard Worker 	DWORD ceu_alloc = 0;
257*1c60b9acSAndroid Build Coastguard Worker 	X509_STORE* store;
258*1c60b9acSAndroid Build Coastguard Worker 	HCERTSTORE hStore;
259*1c60b9acSAndroid Build Coastguard Worker 	int imps = 0;
260*1c60b9acSAndroid Build Coastguard Worker 
261*1c60b9acSAndroid Build Coastguard Worker 	if (lws_check_opt(vhost->options,
262*1c60b9acSAndroid Build Coastguard Worker 			  LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
263*1c60b9acSAndroid Build Coastguard Worker 		return 0;
264*1c60b9acSAndroid Build Coastguard Worker 
265*1c60b9acSAndroid Build Coastguard Worker 	/*
266*1c60b9acSAndroid Build Coastguard Worker 	 * Windows Trust Store code adapted from curl (MIT) openssl.c
267*1c60b9acSAndroid Build Coastguard Worker 	 * https://github.com/warmcat/libwebsockets/pull/2233
268*1c60b9acSAndroid Build Coastguard Worker 	 */
269*1c60b9acSAndroid Build Coastguard Worker 
270*1c60b9acSAndroid Build Coastguard Worker 	store = SSL_CTX_get_cert_store(vhost->tls.ssl_client_ctx);
271*1c60b9acSAndroid Build Coastguard Worker 	hStore = CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL, TEXT("ROOT"));
272*1c60b9acSAndroid Build Coastguard Worker 
273*1c60b9acSAndroid Build Coastguard Worker 	if (!hStore) {
274*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: no store\n", __func__);
275*1c60b9acSAndroid Build Coastguard Worker 		return 1;
276*1c60b9acSAndroid Build Coastguard Worker 	}
277*1c60b9acSAndroid Build Coastguard Worker 
278*1c60b9acSAndroid Build Coastguard Worker 	do {
279*1c60b9acSAndroid Build Coastguard Worker 		const unsigned char* ecert;
280*1c60b9acSAndroid Build Coastguard Worker 		char cert_name[256];
281*1c60b9acSAndroid Build Coastguard Worker 		DWORD req_size = 0;
282*1c60b9acSAndroid Build Coastguard Worker 		BYTE key_usage[2];
283*1c60b9acSAndroid Build Coastguard Worker 		FILETIME ft;
284*1c60b9acSAndroid Build Coastguard Worker 		X509* x509;
285*1c60b9acSAndroid Build Coastguard Worker 
286*1c60b9acSAndroid Build Coastguard Worker 		pcc = CertEnumCertificatesInStore(hStore, pcc);
287*1c60b9acSAndroid Build Coastguard Worker 		if (!pcc)
288*1c60b9acSAndroid Build Coastguard Worker 			break;
289*1c60b9acSAndroid Build Coastguard Worker 
290*1c60b9acSAndroid Build Coastguard Worker 		if (!CertGetNameStringA(pcc, CERT_NAME_SIMPLE_DISPLAY_TYPE,
291*1c60b9acSAndroid Build Coastguard Worker 					0, NULL, cert_name, sizeof(cert_name)))
292*1c60b9acSAndroid Build Coastguard Worker 			strcpy(cert_name, "Unknown");
293*1c60b9acSAndroid Build Coastguard Worker 
294*1c60b9acSAndroid Build Coastguard Worker 		lwsl_debug("%s: Checking cert \"%s\"\n", __func__, cert_name);
295*1c60b9acSAndroid Build Coastguard Worker 
296*1c60b9acSAndroid Build Coastguard Worker 		ecert = (const unsigned char*)pcc->pbCertEncoded;
297*1c60b9acSAndroid Build Coastguard Worker 		if (!ecert)
298*1c60b9acSAndroid Build Coastguard Worker 			continue;
299*1c60b9acSAndroid Build Coastguard Worker 
300*1c60b9acSAndroid Build Coastguard Worker 		GetSystemTimeAsFileTime(&ft);
301*1c60b9acSAndroid Build Coastguard Worker 		if (CompareFileTime(&pcc->pCertInfo->NotBefore, &ft) > 0 ||
302*1c60b9acSAndroid Build Coastguard Worker 		    CompareFileTime(&ft, &pcc->pCertInfo->NotAfter) > 0)
303*1c60b9acSAndroid Build Coastguard Worker 			continue;
304*1c60b9acSAndroid Build Coastguard Worker 
305*1c60b9acSAndroid Build Coastguard Worker 		/* If key usage exists check for signing attribute */
306*1c60b9acSAndroid Build Coastguard Worker 		if (CertGetIntendedKeyUsage(pcc->dwCertEncodingType,
307*1c60b9acSAndroid Build Coastguard Worker 			pcc->pCertInfo,
308*1c60b9acSAndroid Build Coastguard Worker 			key_usage, sizeof(key_usage))) {
309*1c60b9acSAndroid Build Coastguard Worker 			if (!(key_usage[0] & CERT_KEY_CERT_SIGN_KEY_USAGE))
310*1c60b9acSAndroid Build Coastguard Worker 				continue;
311*1c60b9acSAndroid Build Coastguard Worker 		} else
312*1c60b9acSAndroid Build Coastguard Worker 			if (GetLastError())
313*1c60b9acSAndroid Build Coastguard Worker 				continue;
314*1c60b9acSAndroid Build Coastguard Worker 
315*1c60b9acSAndroid Build Coastguard Worker 		/*
316*1c60b9acSAndroid Build Coastguard Worker 		 * If enhanced key usage exists check for server auth attribute.
317*1c60b9acSAndroid Build Coastguard Worker 		 *
318*1c60b9acSAndroid Build Coastguard Worker 		 * Note "In a Microsoft environment, a certificate might also
319*1c60b9acSAndroid Build Coastguard Worker 		 * have EKU extended properties that specify valid uses for the
320*1c60b9acSAndroid Build Coastguard Worker 		 * certificate."
321*1c60b9acSAndroid Build Coastguard Worker 		 * The call below checks both, and behavior varies depending on
322*1c60b9acSAndroid Build Coastguard Worker 		 * what is found. For more details see CertGetEnhancedKeyUsage
323*1c60b9acSAndroid Build Coastguard Worker 		 * doc.
324*1c60b9acSAndroid Build Coastguard Worker 		 */
325*1c60b9acSAndroid Build Coastguard Worker 		if (!CertGetEnhancedKeyUsage(pcc, 0, NULL, &req_size))
326*1c60b9acSAndroid Build Coastguard Worker 			continue;
327*1c60b9acSAndroid Build Coastguard Worker 
328*1c60b9acSAndroid Build Coastguard Worker 		if (req_size && req_size > ceu_alloc) {
329*1c60b9acSAndroid Build Coastguard Worker 			void* tmp = lws_realloc(ceu, req_size, __func__);
330*1c60b9acSAndroid Build Coastguard Worker 
331*1c60b9acSAndroid Build Coastguard Worker 			if (!tmp) {
332*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: OOM", __func__);
333*1c60b9acSAndroid Build Coastguard Worker 				break;
334*1c60b9acSAndroid Build Coastguard Worker 			}
335*1c60b9acSAndroid Build Coastguard Worker 
336*1c60b9acSAndroid Build Coastguard Worker 			ceu = (CERT_ENHKEY_USAGE*)tmp;
337*1c60b9acSAndroid Build Coastguard Worker 			ceu_alloc = req_size;
338*1c60b9acSAndroid Build Coastguard Worker 		}
339*1c60b9acSAndroid Build Coastguard Worker 
340*1c60b9acSAndroid Build Coastguard Worker 		if (!CertGetEnhancedKeyUsage(pcc, 0, ceu, &req_size))
341*1c60b9acSAndroid Build Coastguard Worker 			continue;
342*1c60b9acSAndroid Build Coastguard Worker 
343*1c60b9acSAndroid Build Coastguard Worker 		if (!ceu || (ceu && !ceu->cUsageIdentifier)) {
344*1c60b9acSAndroid Build Coastguard Worker 			/*
345*1c60b9acSAndroid Build Coastguard Worker 			 * "If GetLastError returns CRYPT_E_NOT_FOUND, the
346*1c60b9acSAndroid Build Coastguard Worker 			 * certificate is good for all uses. If it returns
347*1c60b9acSAndroid Build Coastguard Worker 			 * zero, the certificate has no valid uses."
348*1c60b9acSAndroid Build Coastguard Worker 			 */
349*1c60b9acSAndroid Build Coastguard Worker 			if ((HRESULT)GetLastError() != CRYPT_E_NOT_FOUND)
350*1c60b9acSAndroid Build Coastguard Worker 				continue;
351*1c60b9acSAndroid Build Coastguard Worker 
352*1c60b9acSAndroid Build Coastguard Worker 			/* ... allow it... */
353*1c60b9acSAndroid Build Coastguard Worker 
354*1c60b9acSAndroid Build Coastguard Worker 		} else
355*1c60b9acSAndroid Build Coastguard Worker 			if (ceu) {
356*1c60b9acSAndroid Build Coastguard Worker 				BOOL found = FALSE;
357*1c60b9acSAndroid Build Coastguard Worker 				DWORD i;
358*1c60b9acSAndroid Build Coastguard Worker 
359*1c60b9acSAndroid Build Coastguard Worker 				/*
360*1c60b9acSAndroid Build Coastguard Worker 				 * If there is a CEU, check that it specifies
361*1c60b9acSAndroid Build Coastguard Worker 				 * we can use the cert for server validation
362*1c60b9acSAndroid Build Coastguard Worker 				 */
363*1c60b9acSAndroid Build Coastguard Worker 
364*1c60b9acSAndroid Build Coastguard Worker 				for (i = 0; i < ceu->cUsageIdentifier; i++) {
365*1c60b9acSAndroid Build Coastguard Worker 					if (strcmp("1.3.6.1.5.5.7.3.1"
366*1c60b9acSAndroid Build Coastguard Worker 						   /* OID server auth */,
367*1c60b9acSAndroid Build Coastguard Worker 						   ceu->rgpszUsageIdentifier[i]))
368*1c60b9acSAndroid Build Coastguard Worker 						continue;
369*1c60b9acSAndroid Build Coastguard Worker 
370*1c60b9acSAndroid Build Coastguard Worker 					found = TRUE;
371*1c60b9acSAndroid Build Coastguard Worker 					break;
372*1c60b9acSAndroid Build Coastguard Worker 				}
373*1c60b9acSAndroid Build Coastguard Worker 
374*1c60b9acSAndroid Build Coastguard Worker 				if (!found)
375*1c60b9acSAndroid Build Coastguard Worker 					/* Don't use cert if no usage match */
376*1c60b9acSAndroid Build Coastguard Worker 					continue;
377*1c60b9acSAndroid Build Coastguard Worker 			}
378*1c60b9acSAndroid Build Coastguard Worker 
379*1c60b9acSAndroid Build Coastguard Worker 		x509 = d2i_X509(NULL, &ecert, pcc->cbCertEncoded);
380*1c60b9acSAndroid Build Coastguard Worker 		if (!x509)
381*1c60b9acSAndroid Build Coastguard Worker 			/* We can't parse it as am X.509, skip it */
382*1c60b9acSAndroid Build Coastguard Worker 			continue;
383*1c60b9acSAndroid Build Coastguard Worker 
384*1c60b9acSAndroid Build Coastguard Worker 		if (X509_STORE_add_cert(store, x509) == 1) {
385*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s: Imported cert \"%s\"\n", __func__,
386*1c60b9acSAndroid Build Coastguard Worker 				  cert_name);
387*1c60b9acSAndroid Build Coastguard Worker 			imps++;
388*1c60b9acSAndroid Build Coastguard Worker 		}
389*1c60b9acSAndroid Build Coastguard Worker 
390*1c60b9acSAndroid Build Coastguard Worker 		/*
391*1c60b9acSAndroid Build Coastguard Worker 		 * Treat failure as nonfatal, eg, may be dupe
392*1c60b9acSAndroid Build Coastguard Worker 		 */
393*1c60b9acSAndroid Build Coastguard Worker 
394*1c60b9acSAndroid Build Coastguard Worker 		X509_free(x509);
395*1c60b9acSAndroid Build Coastguard Worker 	} while (1);
396*1c60b9acSAndroid Build Coastguard Worker 
397*1c60b9acSAndroid Build Coastguard Worker 	lws_free(ceu);
398*1c60b9acSAndroid Build Coastguard Worker 	CertFreeCertificateContext(pcc);
399*1c60b9acSAndroid Build Coastguard Worker 	CertCloseStore(hStore, 0);
400*1c60b9acSAndroid Build Coastguard Worker 
401*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("%s: Imported %d certs from plat store\n", __func__, imps);
402*1c60b9acSAndroid Build Coastguard Worker #endif
403*1c60b9acSAndroid Build Coastguard Worker 
404*1c60b9acSAndroid Build Coastguard Worker 	return 0;
405*1c60b9acSAndroid Build Coastguard Worker }
406*1c60b9acSAndroid Build Coastguard Worker 
407*1c60b9acSAndroid Build Coastguard Worker #endif
408*1c60b9acSAndroid Build Coastguard Worker 
409*1c60b9acSAndroid Build Coastguard Worker const char *
lws_plat_inet_ntop(int af,const void * src,char * dst,socklen_t cnt)410*1c60b9acSAndroid Build Coastguard Worker lws_plat_inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
411*1c60b9acSAndroid Build Coastguard Worker {
412*1c60b9acSAndroid Build Coastguard Worker 	WCHAR *buffer;
413*1c60b9acSAndroid Build Coastguard Worker 	size_t bufferlen = (size_t)cnt;
414*1c60b9acSAndroid Build Coastguard Worker 	BOOL ok = FALSE;
415*1c60b9acSAndroid Build Coastguard Worker 
416*1c60b9acSAndroid Build Coastguard Worker 	buffer = lws_malloc(bufferlen * 2, "inet_ntop");
417*1c60b9acSAndroid Build Coastguard Worker 	if (!buffer) {
418*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("Out of memory\n");
419*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
420*1c60b9acSAndroid Build Coastguard Worker 	}
421*1c60b9acSAndroid Build Coastguard Worker 
422*1c60b9acSAndroid Build Coastguard Worker 	if (af == AF_INET) {
423*1c60b9acSAndroid Build Coastguard Worker 		struct sockaddr_in srcaddr;
424*1c60b9acSAndroid Build Coastguard Worker 		memset(&srcaddr, 0, sizeof(srcaddr));
425*1c60b9acSAndroid Build Coastguard Worker 		srcaddr.sin_family = AF_INET;
426*1c60b9acSAndroid Build Coastguard Worker 		memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr));
427*1c60b9acSAndroid Build Coastguard Worker 
428*1c60b9acSAndroid Build Coastguard Worker 		if (!WSAAddressToStringW((struct sockaddr*)&srcaddr,
429*1c60b9acSAndroid Build Coastguard Worker 					sizeof(srcaddr), 0, buffer,
430*1c60b9acSAndroid Build Coastguard Worker 					(LPDWORD)&bufferlen))
431*1c60b9acSAndroid Build Coastguard Worker 			ok = TRUE;
432*1c60b9acSAndroid Build Coastguard Worker #ifdef LWS_WITH_IPV6
433*1c60b9acSAndroid Build Coastguard Worker 	} else if (af == AF_INET6) {
434*1c60b9acSAndroid Build Coastguard Worker 		struct sockaddr_in6 srcaddr;
435*1c60b9acSAndroid Build Coastguard Worker 		memset(&srcaddr, 0, sizeof(srcaddr));
436*1c60b9acSAndroid Build Coastguard Worker 		srcaddr.sin6_family = AF_INET6;
437*1c60b9acSAndroid Build Coastguard Worker 		memcpy(&(srcaddr.sin6_addr), src, sizeof(srcaddr.sin6_addr));
438*1c60b9acSAndroid Build Coastguard Worker 
439*1c60b9acSAndroid Build Coastguard Worker 		if (!WSAAddressToStringW((struct sockaddr*)&srcaddr,
440*1c60b9acSAndroid Build Coastguard Worker 					 sizeof(srcaddr), 0, buffer,
441*1c60b9acSAndroid Build Coastguard Worker 					 (LPDWORD)&bufferlen))
442*1c60b9acSAndroid Build Coastguard Worker 			ok = TRUE;
443*1c60b9acSAndroid Build Coastguard Worker #endif
444*1c60b9acSAndroid Build Coastguard Worker 	} else
445*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("Unsupported type\n");
446*1c60b9acSAndroid Build Coastguard Worker 
447*1c60b9acSAndroid Build Coastguard Worker 	if (!ok) {
448*1c60b9acSAndroid Build Coastguard Worker 		int rv = WSAGetLastError();
449*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("WSAAddressToString() : %d\n", rv);
450*1c60b9acSAndroid Build Coastguard Worker 	} else {
451*1c60b9acSAndroid Build Coastguard Worker 		if (WideCharToMultiByte(CP_ACP, 0, buffer, (int)bufferlen, dst,
452*1c60b9acSAndroid Build Coastguard Worker 					cnt, 0, NULL) <= 0)
453*1c60b9acSAndroid Build Coastguard Worker 			ok = FALSE;
454*1c60b9acSAndroid Build Coastguard Worker 	}
455*1c60b9acSAndroid Build Coastguard Worker 
456*1c60b9acSAndroid Build Coastguard Worker 	lws_free(buffer);
457*1c60b9acSAndroid Build Coastguard Worker 	return ok ? dst : NULL;
458*1c60b9acSAndroid Build Coastguard Worker }
459*1c60b9acSAndroid Build Coastguard Worker 
460*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_inet_pton(int af,const char * src,void * dst)461*1c60b9acSAndroid Build Coastguard Worker lws_plat_inet_pton(int af, const char *src, void *dst)
462*1c60b9acSAndroid Build Coastguard Worker {
463*1c60b9acSAndroid Build Coastguard Worker 	WCHAR *buffer;
464*1c60b9acSAndroid Build Coastguard Worker 	size_t bufferlen = strlen(src) + 1;
465*1c60b9acSAndroid Build Coastguard Worker 	BOOL ok = FALSE;
466*1c60b9acSAndroid Build Coastguard Worker 
467*1c60b9acSAndroid Build Coastguard Worker 	buffer = lws_malloc(bufferlen * 2, "inet_pton");
468*1c60b9acSAndroid Build Coastguard Worker 	if (!buffer) {
469*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("Out of memory\n");
470*1c60b9acSAndroid Build Coastguard Worker 		return -1;
471*1c60b9acSAndroid Build Coastguard Worker 	}
472*1c60b9acSAndroid Build Coastguard Worker 
473*1c60b9acSAndroid Build Coastguard Worker 	if (MultiByteToWideChar(CP_ACP, 0, src, (int)bufferlen, buffer,
474*1c60b9acSAndroid Build Coastguard Worker 				(int)bufferlen) <= 0) {
475*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("Failed to convert multi byte to wide char\n");
476*1c60b9acSAndroid Build Coastguard Worker 		lws_free(buffer);
477*1c60b9acSAndroid Build Coastguard Worker 		return -1;
478*1c60b9acSAndroid Build Coastguard Worker 	}
479*1c60b9acSAndroid Build Coastguard Worker 
480*1c60b9acSAndroid Build Coastguard Worker 	if (af == AF_INET) {
481*1c60b9acSAndroid Build Coastguard Worker 		struct sockaddr_in dstaddr;
482*1c60b9acSAndroid Build Coastguard Worker 		int dstaddrlen = sizeof(dstaddr);
483*1c60b9acSAndroid Build Coastguard Worker 
484*1c60b9acSAndroid Build Coastguard Worker 		memset(&dstaddr, 0, sizeof(dstaddr));
485*1c60b9acSAndroid Build Coastguard Worker 		dstaddr.sin_family = AF_INET;
486*1c60b9acSAndroid Build Coastguard Worker 
487*1c60b9acSAndroid Build Coastguard Worker 		if (!WSAStringToAddressW(buffer, af, 0, (struct sockaddr *) &dstaddr, &dstaddrlen)) {
488*1c60b9acSAndroid Build Coastguard Worker 			ok = TRUE;
489*1c60b9acSAndroid Build Coastguard Worker 			memcpy(dst, &dstaddr.sin_addr, sizeof(dstaddr.sin_addr));
490*1c60b9acSAndroid Build Coastguard Worker 		}
491*1c60b9acSAndroid Build Coastguard Worker #ifdef LWS_WITH_IPV6
492*1c60b9acSAndroid Build Coastguard Worker 	} else if (af == AF_INET6) {
493*1c60b9acSAndroid Build Coastguard Worker 		struct sockaddr_in6 dstaddr;
494*1c60b9acSAndroid Build Coastguard Worker 		int dstaddrlen = sizeof(dstaddr);
495*1c60b9acSAndroid Build Coastguard Worker 
496*1c60b9acSAndroid Build Coastguard Worker 		memset(&dstaddr, 0, sizeof(dstaddr));
497*1c60b9acSAndroid Build Coastguard Worker 		dstaddr.sin6_family = AF_INET6;
498*1c60b9acSAndroid Build Coastguard Worker 
499*1c60b9acSAndroid Build Coastguard Worker 		if (!WSAStringToAddressW(buffer, af, 0, (struct sockaddr *) &dstaddr, &dstaddrlen)) {
500*1c60b9acSAndroid Build Coastguard Worker 			ok = TRUE;
501*1c60b9acSAndroid Build Coastguard Worker 			memcpy(dst, &dstaddr.sin6_addr, sizeof(dstaddr.sin6_addr));
502*1c60b9acSAndroid Build Coastguard Worker 		}
503*1c60b9acSAndroid Build Coastguard Worker #endif
504*1c60b9acSAndroid Build Coastguard Worker 	} else
505*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("Unsupported type\n");
506*1c60b9acSAndroid Build Coastguard Worker 
507*1c60b9acSAndroid Build Coastguard Worker 	if (!ok) {
508*1c60b9acSAndroid Build Coastguard Worker 		int rv = WSAGetLastError();
509*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("WSAAddressToString() : %d\n", rv);
510*1c60b9acSAndroid Build Coastguard Worker 	}
511*1c60b9acSAndroid Build Coastguard Worker 
512*1c60b9acSAndroid Build Coastguard Worker 	lws_free(buffer);
513*1c60b9acSAndroid Build Coastguard Worker 	return ok ? 1 : -1;
514*1c60b9acSAndroid Build Coastguard Worker }
515*1c60b9acSAndroid Build Coastguard Worker 
516*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_ifname_to_hwaddr(int fd,const char * ifname,uint8_t * hwaddr,int len)517*1c60b9acSAndroid Build Coastguard Worker lws_plat_ifname_to_hwaddr(int fd, const char *ifname, uint8_t *hwaddr, int len)
518*1c60b9acSAndroid Build Coastguard Worker {
519*1c60b9acSAndroid Build Coastguard Worker 	lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
520*1c60b9acSAndroid Build Coastguard Worker 
521*1c60b9acSAndroid Build Coastguard Worker 	return -1;
522*1c60b9acSAndroid Build Coastguard Worker }
523*1c60b9acSAndroid Build Coastguard Worker 
524*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_rawudp_broadcast(uint8_t * p,const uint8_t * canned,size_t canned_len,size_t n,int fd,const char * iface)525*1c60b9acSAndroid Build Coastguard Worker lws_plat_rawudp_broadcast(uint8_t *p, const uint8_t *canned, size_t canned_len,
526*1c60b9acSAndroid Build Coastguard Worker 			  size_t n, int fd, const char *iface)
527*1c60b9acSAndroid Build Coastguard Worker {
528*1c60b9acSAndroid Build Coastguard Worker 	lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
529*1c60b9acSAndroid Build Coastguard Worker 
530*1c60b9acSAndroid Build Coastguard Worker 	return -1;
531*1c60b9acSAndroid Build Coastguard Worker }
532*1c60b9acSAndroid Build Coastguard Worker 
533*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_if_up(const char * ifname,int fd,int up)534*1c60b9acSAndroid Build Coastguard Worker lws_plat_if_up(const char *ifname, int fd, int up)
535*1c60b9acSAndroid Build Coastguard Worker {
536*1c60b9acSAndroid Build Coastguard Worker 	lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
537*1c60b9acSAndroid Build Coastguard Worker 
538*1c60b9acSAndroid Build Coastguard Worker 	return -1;
539*1c60b9acSAndroid Build Coastguard Worker }
540*1c60b9acSAndroid Build Coastguard Worker 
541*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_BINDTODEVICE(lws_sockfd_type fd,const char * ifname)542*1c60b9acSAndroid Build Coastguard Worker lws_plat_BINDTODEVICE(lws_sockfd_type fd, const char *ifname)
543*1c60b9acSAndroid Build Coastguard Worker {
544*1c60b9acSAndroid Build Coastguard Worker 	lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
545*1c60b9acSAndroid Build Coastguard Worker 
546*1c60b9acSAndroid Build Coastguard Worker 	return -1;
547*1c60b9acSAndroid Build Coastguard Worker }
548*1c60b9acSAndroid Build Coastguard Worker 
549*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_ifconfig(int fd,uint8_t * ip,lws_dhcpc_ifstate_t * is)550*1c60b9acSAndroid Build Coastguard Worker lws_plat_ifconfig(int fd, uint8_t *ip, lws_dhcpc_ifstate_t *is)
551*1c60b9acSAndroid Build Coastguard Worker {
552*1c60b9acSAndroid Build Coastguard Worker 	lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
553*1c60b9acSAndroid Build Coastguard Worker 
554*1c60b9acSAndroid Build Coastguard Worker 	return -1;
555*1c60b9acSAndroid Build Coastguard Worker }
556*1c60b9acSAndroid Build Coastguard Worker 
557*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_MBEDTLS)
558*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_mbedtls_net_send(void * ctx,const uint8_t * buf,size_t len)559*1c60b9acSAndroid Build Coastguard Worker lws_plat_mbedtls_net_send(void *ctx, const uint8_t *buf, size_t len)
560*1c60b9acSAndroid Build Coastguard Worker {
561*1c60b9acSAndroid Build Coastguard Worker 	int fd = ((mbedtls_net_context *) ctx)->fd;
562*1c60b9acSAndroid Build Coastguard Worker 	int ret, en;
563*1c60b9acSAndroid Build Coastguard Worker 
564*1c60b9acSAndroid Build Coastguard Worker 	if (fd < 0)
565*1c60b9acSAndroid Build Coastguard Worker 		return MBEDTLS_ERR_NET_INVALID_CONTEXT;
566*1c60b9acSAndroid Build Coastguard Worker 
567*1c60b9acSAndroid Build Coastguard Worker 	ret = send(fd, buf, (unsigned int)len, 0);
568*1c60b9acSAndroid Build Coastguard Worker 	if (ret >= 0)
569*1c60b9acSAndroid Build Coastguard Worker 		return ret;
570*1c60b9acSAndroid Build Coastguard Worker 
571*1c60b9acSAndroid Build Coastguard Worker 	en = LWS_ERRNO;
572*1c60b9acSAndroid Build Coastguard Worker 	if (en == EAGAIN || en == EWOULDBLOCK)
573*1c60b9acSAndroid Build Coastguard Worker 		return MBEDTLS_ERR_SSL_WANT_WRITE;
574*1c60b9acSAndroid Build Coastguard Worker 
575*1c60b9acSAndroid Build Coastguard Worker 	ret = WSAGetLastError();
576*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("%s: errno %d, GLE %d\n", __func__, en, ret);
577*1c60b9acSAndroid Build Coastguard Worker 	if (ret == WSAECONNRESET )
578*1c60b9acSAndroid Build Coastguard Worker             return( MBEDTLS_ERR_NET_CONN_RESET );
579*1c60b9acSAndroid Build Coastguard Worker 
580*1c60b9acSAndroid Build Coastguard Worker 	return MBEDTLS_ERR_NET_SEND_FAILED;
581*1c60b9acSAndroid Build Coastguard Worker }
582*1c60b9acSAndroid Build Coastguard Worker 
583*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_mbedtls_net_recv(void * ctx,unsigned char * buf,size_t len)584*1c60b9acSAndroid Build Coastguard Worker lws_plat_mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len)
585*1c60b9acSAndroid Build Coastguard Worker {
586*1c60b9acSAndroid Build Coastguard Worker 	int fd = ((mbedtls_net_context *) ctx)->fd;
587*1c60b9acSAndroid Build Coastguard Worker 	int ret, en;
588*1c60b9acSAndroid Build Coastguard Worker 
589*1c60b9acSAndroid Build Coastguard Worker 	if (fd < 0)
590*1c60b9acSAndroid Build Coastguard Worker 		return MBEDTLS_ERR_NET_INVALID_CONTEXT;
591*1c60b9acSAndroid Build Coastguard Worker 
592*1c60b9acSAndroid Build Coastguard Worker 	ret = (int)recv(fd, buf, (unsigned int)len, 0);
593*1c60b9acSAndroid Build Coastguard Worker 	if (ret >= 0)
594*1c60b9acSAndroid Build Coastguard Worker 		return ret;
595*1c60b9acSAndroid Build Coastguard Worker 
596*1c60b9acSAndroid Build Coastguard Worker 	en = LWS_ERRNO;
597*1c60b9acSAndroid Build Coastguard Worker 	if (en == EAGAIN || en == EWOULDBLOCK)
598*1c60b9acSAndroid Build Coastguard Worker 		return MBEDTLS_ERR_SSL_WANT_READ;
599*1c60b9acSAndroid Build Coastguard Worker 
600*1c60b9acSAndroid Build Coastguard Worker 	ret = WSAGetLastError();
601*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("%s: errno %d, GLE %d\n", __func__, en, ret);
602*1c60b9acSAndroid Build Coastguard Worker 
603*1c60b9acSAndroid Build Coastguard Worker         if (ret == WSAECONNRESET)
604*1c60b9acSAndroid Build Coastguard Worker             return MBEDTLS_ERR_NET_CONN_RESET;
605*1c60b9acSAndroid Build Coastguard Worker 
606*1c60b9acSAndroid Build Coastguard Worker 	return MBEDTLS_ERR_NET_RECV_FAILED;
607*1c60b9acSAndroid Build Coastguard Worker }
608*1c60b9acSAndroid Build Coastguard Worker #endif
609*1c60b9acSAndroid Build Coastguard Worker 
610