1d4afb5ceSopenharmony_ci/*
2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation
3d4afb5ceSopenharmony_ci *
4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2020 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
27d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT)
28d4afb5ceSopenharmony_cistatic int
29d4afb5ceSopenharmony_cilws_raw_skt_connect(struct lws *wsi)
30d4afb5ceSopenharmony_ci{
31d4afb5ceSopenharmony_ci	int n;
32d4afb5ceSopenharmony_ci#if defined(LWS_WITH_TLS)
33d4afb5ceSopenharmony_ci	const char *cce = NULL;
34d4afb5ceSopenharmony_ci	char ccebuf[128];
35d4afb5ceSopenharmony_ci
36d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_SYS_ASYNC_DNS)
37d4afb5ceSopenharmony_ci	switch (lws_client_create_tls(wsi, &cce, 1)) {
38d4afb5ceSopenharmony_ci#else
39d4afb5ceSopenharmony_ci	switch (lws_client_create_tls(wsi, &cce, 0)) {
40d4afb5ceSopenharmony_ci#endif
41d4afb5ceSopenharmony_ci	case CCTLS_RETURN_ERROR:
42d4afb5ceSopenharmony_ci		lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce));
43d4afb5ceSopenharmony_ci		return -1;
44d4afb5ceSopenharmony_ci	case CCTLS_RETURN_RETRY:
45d4afb5ceSopenharmony_ci		return 0;
46d4afb5ceSopenharmony_ci	case CCTLS_RETURN_DONE:
47d4afb5ceSopenharmony_ci		break;
48d4afb5ceSopenharmony_ci	}
49d4afb5ceSopenharmony_ci
50d4afb5ceSopenharmony_ci	if (wsi->tls.use_ssl & LCCSCF_USE_SSL) {
51d4afb5ceSopenharmony_ci		n = lws_ssl_client_connect2(wsi, ccebuf, sizeof(ccebuf));
52d4afb5ceSopenharmony_ci		if (n < 0) {
53d4afb5ceSopenharmony_ci			lws_inform_client_conn_fail(wsi, (void *)ccebuf,
54d4afb5ceSopenharmony_ci						    strlen(ccebuf));
55d4afb5ceSopenharmony_ci
56d4afb5ceSopenharmony_ci			return -1;
57d4afb5ceSopenharmony_ci		}
58d4afb5ceSopenharmony_ci		if (n != 1)
59d4afb5ceSopenharmony_ci			return 0; /* wait */
60d4afb5ceSopenharmony_ci	}
61d4afb5ceSopenharmony_ci#endif
62d4afb5ceSopenharmony_ci
63d4afb5ceSopenharmony_ci	n = user_callback_handle_rxflow(wsi->a.protocol->callback,
64d4afb5ceSopenharmony_ci					wsi, wsi->role_ops->adoption_cb[lwsi_role_server(wsi)],
65d4afb5ceSopenharmony_ci					wsi->user_space, NULL, 0);
66d4afb5ceSopenharmony_ci	if (n) {
67d4afb5ceSopenharmony_ci		lws_inform_client_conn_fail(wsi, (void *)"user", 4);
68d4afb5ceSopenharmony_ci		return 1;
69d4afb5ceSopenharmony_ci	}
70d4afb5ceSopenharmony_ci
71d4afb5ceSopenharmony_ci	lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
72d4afb5ceSopenharmony_ci	lwsi_set_state(wsi, LRS_ESTABLISHED);
73d4afb5ceSopenharmony_ci
74d4afb5ceSopenharmony_ci	return 1; /* success */
75d4afb5ceSopenharmony_ci}
76d4afb5ceSopenharmony_ci#endif
77d4afb5ceSopenharmony_ci
78d4afb5ceSopenharmony_cistatic int
79d4afb5ceSopenharmony_cirops_handle_POLLIN_raw_skt(struct lws_context_per_thread *pt, struct lws *wsi,
80d4afb5ceSopenharmony_ci			   struct lws_pollfd *pollfd)
81d4afb5ceSopenharmony_ci{
82d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SOCKS5)
83d4afb5ceSopenharmony_ci	const char *cce = NULL;
84d4afb5ceSopenharmony_ci#endif
85d4afb5ceSopenharmony_ci	struct lws_tokens ebuf;
86d4afb5ceSopenharmony_ci	int n = 0, buffered = 0;
87d4afb5ceSopenharmony_ci
88d4afb5ceSopenharmony_ci	/* pending truncated sends have uber priority */
89d4afb5ceSopenharmony_ci
90d4afb5ceSopenharmony_ci	if (lws_has_buffered_out(wsi)) {
91d4afb5ceSopenharmony_ci		if (!(pollfd->revents & LWS_POLLOUT))
92d4afb5ceSopenharmony_ci			return LWS_HPI_RET_HANDLED;
93d4afb5ceSopenharmony_ci
94d4afb5ceSopenharmony_ci		/* drain the output buflist */
95d4afb5ceSopenharmony_ci		if (lws_issue_raw(wsi, NULL, 0) < 0)
96d4afb5ceSopenharmony_ci			goto fail;
97d4afb5ceSopenharmony_ci		/*
98d4afb5ceSopenharmony_ci		 * we can't afford to allow input processing to send
99d4afb5ceSopenharmony_ci		 * something new, so spin around he event loop until
100d4afb5ceSopenharmony_ci		 * he doesn't have any partials
101d4afb5ceSopenharmony_ci		 */
102d4afb5ceSopenharmony_ci		return LWS_HPI_RET_HANDLED;
103d4afb5ceSopenharmony_ci	}
104d4afb5ceSopenharmony_ci
105d4afb5ceSopenharmony_ci
106d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER)
107d4afb5ceSopenharmony_ci	if (!lwsi_role_client(wsi) &&  lwsi_state(wsi) != LRS_ESTABLISHED) {
108d4afb5ceSopenharmony_ci
109d4afb5ceSopenharmony_ci		lwsl_wsi_debug(wsi, "wsistate 0x%x\n", (int)wsi->wsistate);
110d4afb5ceSopenharmony_ci
111d4afb5ceSopenharmony_ci		if (lwsi_state(wsi) != LRS_SSL_INIT)
112d4afb5ceSopenharmony_ci			if (lws_server_socket_service_ssl(wsi,
113d4afb5ceSopenharmony_ci							  LWS_SOCK_INVALID,
114d4afb5ceSopenharmony_ci				!!(pollfd->revents & pollfd->events & LWS_POLLIN)))
115d4afb5ceSopenharmony_ci				return LWS_HPI_RET_PLEASE_CLOSE_ME;
116d4afb5ceSopenharmony_ci
117d4afb5ceSopenharmony_ci		return LWS_HPI_RET_HANDLED;
118d4afb5ceSopenharmony_ci	}
119d4afb5ceSopenharmony_ci#endif
120d4afb5ceSopenharmony_ci
121d4afb5ceSopenharmony_ci	if ((pollfd->revents & pollfd->events & LWS_POLLIN) &&
122d4afb5ceSopenharmony_ci	    !(wsi->favoured_pollin &&
123d4afb5ceSopenharmony_ci	      (pollfd->revents & pollfd->events & LWS_POLLOUT))) {
124d4afb5ceSopenharmony_ci
125d4afb5ceSopenharmony_ci		lwsl_wsi_debug(wsi, "POLLIN: state 0x%x", lwsi_state(wsi));
126d4afb5ceSopenharmony_ci
127d4afb5ceSopenharmony_ci		switch (lwsi_state(wsi)) {
128d4afb5ceSopenharmony_ci
129d4afb5ceSopenharmony_ci		    /* any tunnel has to have been established... */
130d4afb5ceSopenharmony_ci		case LRS_SSL_ACK_PENDING:
131d4afb5ceSopenharmony_ci			goto nope;
132d4afb5ceSopenharmony_ci		    /* we are actually connected */
133d4afb5ceSopenharmony_ci		case LRS_WAITING_CONNECT:
134d4afb5ceSopenharmony_ci			goto nope;
135d4afb5ceSopenharmony_ci
136d4afb5ceSopenharmony_ci		case LRS_WAITING_SSL:
137d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT)
138d4afb5ceSopenharmony_ci			n = lws_raw_skt_connect(wsi);
139d4afb5ceSopenharmony_ci			if (n < 0)
140d4afb5ceSopenharmony_ci				goto fail;
141d4afb5ceSopenharmony_ci#endif
142d4afb5ceSopenharmony_ci			break;
143d4afb5ceSopenharmony_ci
144d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SOCKS5)
145d4afb5ceSopenharmony_ci
146d4afb5ceSopenharmony_ci		/* SOCKS Greeting Reply */
147d4afb5ceSopenharmony_ci		case LRS_WAITING_SOCKS_GREETING_REPLY:
148d4afb5ceSopenharmony_ci		case LRS_WAITING_SOCKS_AUTH_REPLY:
149d4afb5ceSopenharmony_ci		case LRS_WAITING_SOCKS_CONNECT_REPLY:
150d4afb5ceSopenharmony_ci
151d4afb5ceSopenharmony_ci			switch (lws_socks5c_handle_state(wsi, pollfd, &cce)) {
152d4afb5ceSopenharmony_ci			case LW5CHS_RET_RET0:
153d4afb5ceSopenharmony_ci				goto nope;
154d4afb5ceSopenharmony_ci			case LW5CHS_RET_BAIL3:
155d4afb5ceSopenharmony_ci				lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce));
156d4afb5ceSopenharmony_ci				goto fail;
157d4afb5ceSopenharmony_ci			case LW5CHS_RET_STARTHS:
158d4afb5ceSopenharmony_ci				lwsi_set_state(wsi, LRS_ESTABLISHED);
159d4afb5ceSopenharmony_ci				lws_client_connect_4_established(wsi, NULL, 0);
160d4afb5ceSopenharmony_ci
161d4afb5ceSopenharmony_ci				/*
162d4afb5ceSopenharmony_ci				 * Now we got the socks5 connection, we need to
163d4afb5ceSopenharmony_ci				 * go down the tls path on it now if that's what
164d4afb5ceSopenharmony_ci				 * we want
165d4afb5ceSopenharmony_ci				 */
166d4afb5ceSopenharmony_ci				goto post_rx;
167d4afb5ceSopenharmony_ci
168d4afb5ceSopenharmony_ci			default:
169d4afb5ceSopenharmony_ci				break;
170d4afb5ceSopenharmony_ci			}
171d4afb5ceSopenharmony_ci			goto post_rx;
172d4afb5ceSopenharmony_ci#endif
173d4afb5ceSopenharmony_ci		default:
174d4afb5ceSopenharmony_ci			ebuf.token = NULL;
175d4afb5ceSopenharmony_ci			ebuf.len = 0;
176d4afb5ceSopenharmony_ci
177d4afb5ceSopenharmony_ci			buffered = lws_buflist_aware_read(pt, wsi, &ebuf, 1, __func__);
178d4afb5ceSopenharmony_ci			switch (ebuf.len) {
179d4afb5ceSopenharmony_ci			case 0:
180d4afb5ceSopenharmony_ci				if (wsi->unix_skt)
181d4afb5ceSopenharmony_ci					break;
182d4afb5ceSopenharmony_ci				lwsl_wsi_info(wsi, "read 0 len");
183d4afb5ceSopenharmony_ci				wsi->seen_zero_length_recv = 1;
184d4afb5ceSopenharmony_ci				if (lws_change_pollfd(wsi, LWS_POLLIN, 0))
185d4afb5ceSopenharmony_ci					goto fail;
186d4afb5ceSopenharmony_ci
187d4afb5ceSopenharmony_ci				/*
188d4afb5ceSopenharmony_ci				 * we need to go to fail here, since it's the only
189d4afb5ceSopenharmony_ci				 * chance we get to understand that the socket has
190d4afb5ceSopenharmony_ci				 * closed
191d4afb5ceSopenharmony_ci				 */
192d4afb5ceSopenharmony_ci				// goto try_pollout;
193d4afb5ceSopenharmony_ci				goto fail;
194d4afb5ceSopenharmony_ci
195d4afb5ceSopenharmony_ci			case LWS_SSL_CAPABLE_ERROR:
196d4afb5ceSopenharmony_ci				goto fail;
197d4afb5ceSopenharmony_ci			case LWS_SSL_CAPABLE_MORE_SERVICE:
198d4afb5ceSopenharmony_ci				goto try_pollout;
199d4afb5ceSopenharmony_ci			}
200d4afb5ceSopenharmony_ci
201d4afb5ceSopenharmony_ci#if defined(LWS_WITH_UDP)
202d4afb5ceSopenharmony_ci			if (lws_fi(&wsi->fic, "udp_rx_loss")) {
203d4afb5ceSopenharmony_ci				n = ebuf.len;
204d4afb5ceSopenharmony_ci				goto post_rx;
205d4afb5ceSopenharmony_ci			}
206d4afb5ceSopenharmony_ci#endif
207d4afb5ceSopenharmony_ci
208d4afb5ceSopenharmony_ci			n = user_callback_handle_rxflow(wsi->a.protocol->callback,
209d4afb5ceSopenharmony_ci							wsi, LWS_CALLBACK_RAW_RX,
210d4afb5ceSopenharmony_ci							wsi->user_space, ebuf.token,
211d4afb5ceSopenharmony_ci							(unsigned int)ebuf.len);
212d4afb5ceSopenharmony_ci#if defined(LWS_WITH_UDP) || defined(LWS_WITH_SOCKS5)
213d4afb5ceSopenharmony_cipost_rx:
214d4afb5ceSopenharmony_ci#endif
215d4afb5ceSopenharmony_ci			if (n < 0) {
216d4afb5ceSopenharmony_ci				lwsl_wsi_info(wsi, "LWS_CALLBACK_RAW_RX_fail");
217d4afb5ceSopenharmony_ci				goto fail;
218d4afb5ceSopenharmony_ci			}
219d4afb5ceSopenharmony_ci
220d4afb5ceSopenharmony_ci			if (lws_buflist_aware_finished_consuming(wsi, &ebuf, ebuf.len,
221d4afb5ceSopenharmony_ci								 buffered, __func__))
222d4afb5ceSopenharmony_ci				return LWS_HPI_RET_PLEASE_CLOSE_ME;
223d4afb5ceSopenharmony_ci
224d4afb5ceSopenharmony_ci			goto try_pollout;
225d4afb5ceSopenharmony_ci		}
226d4afb5ceSopenharmony_ci	}
227d4afb5ceSopenharmony_cinope:
228d4afb5ceSopenharmony_ci	if (wsi->favoured_pollin &&
229d4afb5ceSopenharmony_ci	    (pollfd->revents & pollfd->events & LWS_POLLOUT))
230d4afb5ceSopenharmony_ci		/* we balanced the last favouring of pollin */
231d4afb5ceSopenharmony_ci		wsi->favoured_pollin = 0;
232d4afb5ceSopenharmony_ci
233d4afb5ceSopenharmony_citry_pollout:
234d4afb5ceSopenharmony_ci
235d4afb5ceSopenharmony_ci	if (!(pollfd->revents & LWS_POLLOUT))
236d4afb5ceSopenharmony_ci		return LWS_HPI_RET_HANDLED;
237d4afb5ceSopenharmony_ci
238d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT)
239d4afb5ceSopenharmony_ci	if (lwsi_state(wsi) == LRS_WAITING_CONNECT) {
240d4afb5ceSopenharmony_ci	    if (!lws_client_connect_3_connect(wsi, NULL, NULL, 0, NULL))
241d4afb5ceSopenharmony_ci		return LWS_HPI_RET_WSI_ALREADY_DIED;
242d4afb5ceSopenharmony_ci
243d4afb5ceSopenharmony_ci	    if (lws_raw_skt_connect(wsi) < 0)
244d4afb5ceSopenharmony_ci		    goto fail;
245d4afb5ceSopenharmony_ci	}
246d4afb5ceSopenharmony_ci#endif
247d4afb5ceSopenharmony_ci
248d4afb5ceSopenharmony_ci	if (lwsi_state(wsi) == LRS_WAITING_SSL)
249d4afb5ceSopenharmony_ci		return LWS_HPI_RET_HANDLED;
250d4afb5ceSopenharmony_ci
251d4afb5ceSopenharmony_ci	/* one shot */
252d4afb5ceSopenharmony_ci	if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
253d4afb5ceSopenharmony_ci		goto fail;
254d4afb5ceSopenharmony_ci
255d4afb5ceSopenharmony_ci	/* clear back-to-back write detection */
256d4afb5ceSopenharmony_ci	wsi->could_have_pending = 0;
257d4afb5ceSopenharmony_ci
258d4afb5ceSopenharmony_ci	n = user_callback_handle_rxflow(wsi->a.protocol->callback,
259d4afb5ceSopenharmony_ci			wsi, LWS_CALLBACK_RAW_WRITEABLE,
260d4afb5ceSopenharmony_ci			wsi->user_space, NULL, 0);
261d4afb5ceSopenharmony_ci	if (n < 0) {
262d4afb5ceSopenharmony_ci		lwsl_info("writeable_fail\n");
263d4afb5ceSopenharmony_ci		goto fail;
264d4afb5ceSopenharmony_ci	}
265d4afb5ceSopenharmony_ci
266d4afb5ceSopenharmony_ci	return LWS_HPI_RET_HANDLED;
267d4afb5ceSopenharmony_ci
268d4afb5ceSopenharmony_cifail:
269d4afb5ceSopenharmony_ci	lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "raw svc fail");
270d4afb5ceSopenharmony_ci
271d4afb5ceSopenharmony_ci	return LWS_HPI_RET_WSI_ALREADY_DIED;
272d4afb5ceSopenharmony_ci}
273d4afb5ceSopenharmony_ci
274d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER)
275d4afb5ceSopenharmony_cistatic int
276d4afb5ceSopenharmony_cirops_adoption_bind_raw_skt(struct lws *wsi, int type, const char *vh_prot_name)
277d4afb5ceSopenharmony_ci{
278d4afb5ceSopenharmony_ci
279d4afb5ceSopenharmony_ci	// lwsl_notice("%s: bind type %d\n", __func__, type);
280d4afb5ceSopenharmony_ci
281d4afb5ceSopenharmony_ci	/* no http but socket... must be raw skt */
282d4afb5ceSopenharmony_ci	if ((type & LWS_ADOPT_HTTP) || !(type & LWS_ADOPT_SOCKET) ||
283d4afb5ceSopenharmony_ci	    ((type & _LWS_ADOPT_FINISH) && (!(type & LWS_ADOPT_FLAG_UDP))))
284d4afb5ceSopenharmony_ci		return 0; /* no match */
285d4afb5ceSopenharmony_ci
286d4afb5ceSopenharmony_ci#if defined(LWS_WITH_UDP)
287d4afb5ceSopenharmony_ci	if ((type & LWS_ADOPT_FLAG_UDP) && !wsi->udp) {
288d4afb5ceSopenharmony_ci		/*
289d4afb5ceSopenharmony_ci		 * these can be >128 bytes, so just alloc for UDP
290d4afb5ceSopenharmony_ci		 */
291d4afb5ceSopenharmony_ci		wsi->udp = lws_malloc(sizeof(*wsi->udp), "udp struct");
292d4afb5ceSopenharmony_ci		if (!wsi->udp)
293d4afb5ceSopenharmony_ci			return 0;
294d4afb5ceSopenharmony_ci		memset(wsi->udp, 0, sizeof(*wsi->udp));
295d4afb5ceSopenharmony_ci	}
296d4afb5ceSopenharmony_ci#endif
297d4afb5ceSopenharmony_ci
298d4afb5ceSopenharmony_ci	lws_role_transition(wsi, 0, (type & LWS_ADOPT_ALLOW_SSL) ? LRS_SSL_INIT :
299d4afb5ceSopenharmony_ci				LRS_ESTABLISHED, &role_ops_raw_skt);
300d4afb5ceSopenharmony_ci
301d4afb5ceSopenharmony_ci	if (vh_prot_name)
302d4afb5ceSopenharmony_ci		lws_bind_protocol(wsi, wsi->a.protocol, __func__);
303d4afb5ceSopenharmony_ci	else
304d4afb5ceSopenharmony_ci		/* this is the only time he will transition */
305d4afb5ceSopenharmony_ci		lws_bind_protocol(wsi,
306d4afb5ceSopenharmony_ci			&wsi->a.vhost->protocols[wsi->a.vhost->raw_protocol_index],
307d4afb5ceSopenharmony_ci			__func__);
308d4afb5ceSopenharmony_ci
309d4afb5ceSopenharmony_ci	return 1; /* bound */
310d4afb5ceSopenharmony_ci}
311d4afb5ceSopenharmony_ci#endif
312d4afb5ceSopenharmony_ci
313d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT)
314d4afb5ceSopenharmony_cistatic int
315d4afb5ceSopenharmony_cirops_client_bind_raw_skt(struct lws *wsi,
316d4afb5ceSopenharmony_ci			 const struct lws_client_connect_info *i)
317d4afb5ceSopenharmony_ci{
318d4afb5ceSopenharmony_ci	if (!i) {
319d4afb5ceSopenharmony_ci
320d4afb5ceSopenharmony_ci		/* finalize */
321d4afb5ceSopenharmony_ci
322d4afb5ceSopenharmony_ci		if (!wsi->user_space && wsi->stash->cis[CIS_METHOD])
323d4afb5ceSopenharmony_ci			if (lws_ensure_user_space(wsi))
324d4afb5ceSopenharmony_ci				return 1;
325d4afb5ceSopenharmony_ci
326d4afb5ceSopenharmony_ci		return 0;
327d4afb5ceSopenharmony_ci	}
328d4afb5ceSopenharmony_ci
329d4afb5ceSopenharmony_ci	/* we are a fallback if nothing else matched */
330d4afb5ceSopenharmony_ci
331d4afb5ceSopenharmony_ci	if (!i->local_protocol_name ||
332d4afb5ceSopenharmony_ci	    strcmp(i->local_protocol_name, "raw-proxy"))
333d4afb5ceSopenharmony_ci		lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED,
334d4afb5ceSopenharmony_ci			    &role_ops_raw_skt);
335d4afb5ceSopenharmony_ci
336d4afb5ceSopenharmony_ci	return 1; /* matched */
337d4afb5ceSopenharmony_ci}
338d4afb5ceSopenharmony_ci#endif
339d4afb5ceSopenharmony_ci
340d4afb5ceSopenharmony_cistatic const lws_rops_t rops_table_raw_skt[] = {
341d4afb5ceSopenharmony_ci	/*  1 */ { .handle_POLLIN	  = rops_handle_POLLIN_raw_skt },
342d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER)
343d4afb5ceSopenharmony_ci	/*  2 */ { .adoption_bind	  = rops_adoption_bind_raw_skt },
344d4afb5ceSopenharmony_ci#else
345d4afb5ceSopenharmony_ci	/*  2 */ { .adoption_bind	  = NULL },
346d4afb5ceSopenharmony_ci#endif
347d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT)
348d4afb5ceSopenharmony_ci	/*  3 */ { .client_bind		  = rops_client_bind_raw_skt },
349d4afb5ceSopenharmony_ci#endif
350d4afb5ceSopenharmony_ci};
351d4afb5ceSopenharmony_ci
352d4afb5ceSopenharmony_ciconst struct lws_role_ops role_ops_raw_skt = {
353d4afb5ceSopenharmony_ci	/* role name */			"raw-skt",
354d4afb5ceSopenharmony_ci	/* alpn id */			NULL,
355d4afb5ceSopenharmony_ci
356d4afb5ceSopenharmony_ci	/* rops_table */		rops_table_raw_skt,
357d4afb5ceSopenharmony_ci	/* rops_idx */			{
358d4afb5ceSopenharmony_ci	  /* LWS_ROPS_check_upgrades */
359d4afb5ceSopenharmony_ci	  /* LWS_ROPS_pt_init_destroy */		0x00,
360d4afb5ceSopenharmony_ci	  /* LWS_ROPS_init_vhost */
361d4afb5ceSopenharmony_ci	  /* LWS_ROPS_destroy_vhost */			0x00,
362d4afb5ceSopenharmony_ci	  /* LWS_ROPS_service_flag_pending */
363d4afb5ceSopenharmony_ci	  /* LWS_ROPS_handle_POLLIN */			0x01,
364d4afb5ceSopenharmony_ci	  /* LWS_ROPS_handle_POLLOUT */
365d4afb5ceSopenharmony_ci	  /* LWS_ROPS_perform_user_POLLOUT */		0x00,
366d4afb5ceSopenharmony_ci	  /* LWS_ROPS_callback_on_writable */
367d4afb5ceSopenharmony_ci	  /* LWS_ROPS_tx_credit */			0x00,
368d4afb5ceSopenharmony_ci	  /* LWS_ROPS_write_role_protocol */
369d4afb5ceSopenharmony_ci	  /* LWS_ROPS_encapsulation_parent */		0x00,
370d4afb5ceSopenharmony_ci	  /* LWS_ROPS_alpn_negotiated */
371d4afb5ceSopenharmony_ci	  /* LWS_ROPS_close_via_role_protocol */	0x00,
372d4afb5ceSopenharmony_ci	  /* LWS_ROPS_close_role */
373d4afb5ceSopenharmony_ci	  /* LWS_ROPS_close_kill_connection */		0x00,
374d4afb5ceSopenharmony_ci	  /* LWS_ROPS_destroy_role */
375d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER)
376d4afb5ceSopenharmony_ci	  /* LWS_ROPS_adoption_bind */			0x02,
377d4afb5ceSopenharmony_ci#else
378d4afb5ceSopenharmony_ci	  /* LWS_ROPS_adoption_bind */			0x00,
379d4afb5ceSopenharmony_ci#endif
380d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT)
381d4afb5ceSopenharmony_ci	  /* LWS_ROPS_client_bind */
382d4afb5ceSopenharmony_ci	  /* LWS_ROPS_issue_keepalive */		0x30,
383d4afb5ceSopenharmony_ci#else
384d4afb5ceSopenharmony_ci	  /* LWS_ROPS_client_bind */
385d4afb5ceSopenharmony_ci	  /* LWS_ROPS_issue_keepalive */		0x00,
386d4afb5ceSopenharmony_ci#endif
387d4afb5ceSopenharmony_ci					},
388d4afb5ceSopenharmony_ci
389d4afb5ceSopenharmony_ci	/* adoption_cb clnt, srv */	{ LWS_CALLBACK_RAW_CONNECTED,
390d4afb5ceSopenharmony_ci					  LWS_CALLBACK_RAW_ADOPT },
391d4afb5ceSopenharmony_ci	/* rx_cb clnt, srv */		{ LWS_CALLBACK_RAW_RX,
392d4afb5ceSopenharmony_ci					  LWS_CALLBACK_RAW_RX },
393d4afb5ceSopenharmony_ci	/* writeable cb clnt, srv */	{ LWS_CALLBACK_RAW_WRITEABLE,
394d4afb5ceSopenharmony_ci					  LWS_CALLBACK_RAW_WRITEABLE},
395d4afb5ceSopenharmony_ci	/* close cb clnt, srv */	{ LWS_CALLBACK_RAW_CLOSE,
396d4afb5ceSopenharmony_ci					  LWS_CALLBACK_RAW_CLOSE },
397d4afb5ceSopenharmony_ci	/* protocol_bind cb c, srv */	{ LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL,
398d4afb5ceSopenharmony_ci					  LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL },
399d4afb5ceSopenharmony_ci	/* protocol_unbind cb c, srv */	{ LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL,
400d4afb5ceSopenharmony_ci					  LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL },
401d4afb5ceSopenharmony_ci	/* file_handle */		0,
402d4afb5ceSopenharmony_ci};
403