1/*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
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
25#include "private-lib-core.h"
26
27#if defined(LWS_WITH_MBEDTLS)
28#if defined(LWS_HAVE_MBEDTLS_NET_SOCKETS)
29#include "mbedtls/net_sockets.h"
30#else
31#include "mbedtls/net.h"
32#endif
33#endif
34
35int
36lws_plat_pipe_create(struct lws *wsi)
37{
38	return 1;
39}
40
41int
42lws_plat_pipe_signal(struct lws *wsi)
43{
44	return 1;
45}
46
47void
48lws_plat_pipe_close(struct lws *wsi)
49{
50}
51
52int
53lws_send_pipe_choked(struct lws *wsi)
54{
55	struct lws *wsi_eff;
56
57#if defined(LWS_WITH_HTTP2)
58	wsi_eff = lws_get_network_wsi(wsi);
59#else
60	wsi_eff = wsi;
61#endif
62
63	/* the fact we checked implies we avoided back-to-back writes */
64	wsi_eff->could_have_pending = 0;
65
66	/* treat the fact we got a truncated send pending as if we're choked */
67	if (lws_has_buffered_out(wsi_eff)
68#if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
69	    || wsi->http.comp_ctx.buflist_comp ||
70	       wsi->http.comp_ctx.may_have_more
71#endif
72	)
73		return 1;
74
75	/* okay to send another packet without blocking */
76
77	return 0;
78}
79
80int
81lws_poll_listen_fd(struct lws_pollfd *fd)
82{
83//	return poll(fd, 1, 0);
84
85	return 0;
86}
87
88
89int
90_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
91{
92	lws_usec_t timeout_us = timeout_ms * LWS_US_PER_MS;
93	struct lws_context_per_thread *pt;
94	int n = -1, m, c, a = 0;
95	//char buf;
96
97	/* stay dead once we are dead */
98
99	if (!context)
100		return 1;
101
102	pt = &context->pt[tsi];
103
104	if (timeout_ms < 0)
105		timeout_ms = 0;
106	else
107		timeout_ms = 2000000000;
108
109	if (!pt->service_tid_detected && context->vhost_list) {
110		struct lws _lws;
111
112		memset(&_lws, 0, sizeof(_lws));
113		_lws.context = context;
114
115		pt->service_tid = context->vhost_list->protocols[0].callback(
116			&_lws, LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
117		pt->service_tid_detected = 1;
118	}
119
120	/*
121	 * is there anybody with pending stuff that needs service forcing?
122	 */
123	if (lws_service_adjust_timeout(context, 1, tsi)) {
124again:
125		a = 0;
126		if (timeout_us) {
127			lws_usec_t us;
128
129			lws_pt_lock(pt, __func__);
130			/* don't stay in poll wait longer than next hr timeout */
131			us = __lws_sul_service_ripe(pt->pt_sul_owner,
132						    LWS_COUNT_PT_SUL_OWNERS,
133						    lws_now_usecs());
134			if (us && us < timeout_us)
135				timeout_us = us;
136
137			lws_pt_unlock(pt);
138		}
139
140		n = poll(pt->fds, pt->fds_count, timeout_us / LWS_US_PER_MS);
141
142		m = 0;
143
144		if (pt->context->tls_ops &&
145		    pt->context->tls_ops->fake_POLLIN_for_buffered)
146			m = pt->context->tls_ops->fake_POLLIN_for_buffered(pt);
147
148		if (/*!pt->ws.rx_draining_ext_list && */!m && !n) /* nothing to do */
149			return 0;
150	} else
151		a = 1;
152
153	m = lws_service_flag_pending(context, tsi);
154	if (m)
155		c = -1; /* unknown limit */
156	else
157		if (n < 0) {
158			if (LWS_ERRNO != LWS_EINTR)
159				return -1;
160			return 0;
161		} else
162			c = n;
163
164	/* any socket with events to service? */
165	for (n = 0; n < (int)pt->fds_count && c; n++) {
166		if (!pt->fds[n].revents)
167			continue;
168
169		c--;
170#if 0
171		if (pt->fds[n].fd == pt->dummy_pipe_fds[0]) {
172			if (read(pt->fds[n].fd, &buf, 1) != 1)
173				lwsl_err("Cannot read from dummy pipe.");
174			continue;
175		}
176#endif
177		m = lws_service_fd_tsi(context, &pt->fds[n], tsi);
178		if (m < 0)
179			return -1;
180		/* if something closed, retry this slot */
181		if (m)
182			n--;
183	}
184
185	if (a)
186		goto again;
187
188	return 0;
189}
190
191int
192lws_plat_service(struct lws_context *context, int timeout_ms)
193{
194	return _lws_plat_service_tsi(context, timeout_ms, 0);
195}
196
197int
198lws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt)
199{
200	return 0;
201}
202
203
204int
205lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
206			size_t len)
207{
208	return 1;
209}
210
211
212/* cast a struct sockaddr_in6 * into addr for ipv6 */
213
214int
215lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
216		    size_t addrlen)
217{
218	return -1;
219}
220
221void
222lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
223{
224	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
225
226	pt->fds[pt->fds_count++].revents = 0;
227}
228
229void
230lws_plat_delete_socket_from_fds(struct lws_context *context,
231						struct lws *wsi, int m)
232{
233	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
234
235	pt->fds_count--;
236}
237
238int
239lws_plat_change_pollfd(struct lws_context *context,
240		      struct lws *wsi, struct lws_pollfd *pfd)
241{
242	return 0;
243}
244
245const char *
246lws_plat_inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
247{
248	//return inet_ntop(af, src, dst, cnt);
249	return "lws_plat_inet_ntop";
250}
251
252int
253lws_plat_inet_pton(int af, const char *src, void *dst)
254{
255	//return inet_pton(af, src, dst);
256	return 1;
257}
258
259int
260lws_plat_set_socket_options_ip(int fd, uint8_t pri, unsigned int lws_flags)
261{
262	return 0;
263}
264
265int
266lws_plat_vhost_tls_client_ctx_init(struct lws_vhost *vhost)
267{
268	return 0;
269}
270
271#if defined(LWS_WITH_MBEDTLS)
272int
273lws_plat_mbedtls_net_send(void *ctx, const uint8_t *buf, size_t len)
274{
275	int fd = ((mbedtls_net_context *) ctx)->fd;
276	int ret;
277
278	if (fd < 0)
279		return MBEDTLS_ERR_NET_INVALID_CONTEXT;
280
281	ret = write(fd, buf, len);
282	if (ret >= 0)
283		return ret;
284
285	if (errno == EAGAIN || errno == EWOULDBLOCK)
286		return MBEDTLS_ERR_SSL_WANT_WRITE;
287
288	if (errno == EPIPE || errno == ECONNRESET)
289		return MBEDTLS_ERR_NET_CONN_RESET;
290
291	if( errno == EINTR )
292		return MBEDTLS_ERR_SSL_WANT_WRITE;
293
294	return MBEDTLS_ERR_NET_SEND_FAILED;
295}
296
297int
298lws_plat_mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len)
299{
300	int fd = ((mbedtls_net_context *) ctx)->fd;
301	int ret;
302
303	if (fd < 0)
304		return MBEDTLS_ERR_NET_INVALID_CONTEXT;
305
306	ret = (int)read(fd, buf, len);
307	if (ret >= 0)
308		return ret;
309
310	if (errno == EAGAIN || errno == EWOULDBLOCK)
311		return MBEDTLS_ERR_SSL_WANT_READ;
312
313	if (errno == EPIPE || errno == ECONNRESET)
314		return MBEDTLS_ERR_NET_CONN_RESET;
315
316	if (errno == EINTR)
317		return MBEDTLS_ERR_SSL_WANT_READ;
318
319	return MBEDTLS_ERR_NET_RECV_FAILED;
320}
321
322#endif
323