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 /*
28  * notice this returns number of bytes consumed, or -1
29  */
30 int
lws_issue_raw(struct lws * wsi,unsigned char * buf,size_t len)31 lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len)
32 {
33 	struct lws_context *context = lws_get_context(wsi);
34 	size_t real_len = len;
35 	unsigned int n, m;
36 
37 	/*
38 	 * If you're looking to dump data being sent down the tls tunnel, see
39 	 * lws_ssl_capable_write() in lib/tls/mbedtls/mbedtls-ssl.c or
40 	 * lib/tls/openssl/openssl-ssl.c.
41 	 *
42 	 * There's also a corresponding lws_ssl_capable_read() in those files
43 	 * where you can enable a dump of decrypted data as soon as it was
44 	 * read.
45 	 */
46 
47 	/*
48 	 * Detect if we got called twice without going through the
49 	 * event loop to handle pending.  Since that guarantees extending any
50 	 * existing buflist_out it's inefficient.
51 	 */
52 	if (0 && buf && wsi->could_have_pending) {
53 		lwsl_hexdump_level(LLL_INFO, buf, len);
54 		lwsl_info("** %s: vh: %s, prot: %s, role %s: "
55 			  "Inefficient back-to-back write of %lu detected...\n",
56 			  lws_wsi_tag(wsi), lws_vh_tag(wsi->a.vhost),
57 			  wsi->a.protocol->name, wsi->role_ops->name,
58 			  (unsigned long)len);
59 	}
60 
61 	/* just ignore sends after we cleared the truncation buffer */
62 	if (lwsi_state(wsi) == LRS_FLUSHING_BEFORE_CLOSE &&
63 	    !lws_has_buffered_out(wsi)
64 #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
65 	    && !wsi->http.comp_ctx.may_have_more
66 #endif
67 	    )
68 		return (int)len;
69 
70 	if (buf && lws_has_buffered_out(wsi)) {
71 		lwsl_info("** %s: vh: %s, prot: %s, incr buflist_out by %lu\n",
72 			  lws_wsi_tag(wsi), lws_vh_tag(wsi->a.vhost),
73 			  wsi->a.protocol->name, (unsigned long)len);
74 
75 		/*
76 		 * already buflist ahead of this, add it on the tail of the
77 		 * buflist, then ignore it for now and act like we're flushing
78 		 * the buflist...
79 		 */
80 
81 		if (lws_buflist_append_segment(&wsi->buflist_out, buf, len))
82 			return -1;
83 
84 		buf = NULL;
85 		len = 0;
86 	}
87 
88 	if (wsi->buflist_out) {
89 		/* we have to drain the earliest buflist_out stuff first */
90 
91 		len = lws_buflist_next_segment_len(&wsi->buflist_out, &buf);
92 		real_len = len;
93 
94 		lwsl_debug("%s: draining %d\n", __func__, (int)len);
95 	}
96 
97 	if (!len || !buf)
98 		return 0;
99 
100 	if (!wsi->mux_substream && !lws_socket_is_valid(wsi->desc.sockfd))
101 		lwsl_err("%s: %s invalid sock\n", __func__, lws_wsi_tag(wsi));
102 
103 	/* limit sending */
104 	if (wsi->a.protocol->tx_packet_size)
105 		n = (unsigned int)wsi->a.protocol->tx_packet_size;
106 	else {
107 		n = (unsigned int)wsi->a.protocol->rx_buffer_size;
108 		if (!n)
109 			n = context->pt_serv_buf_size;
110 	}
111 	n += LWS_PRE + 4;
112 	if (n > len)
113 		n = (unsigned int)len;
114 
115 	/* nope, send it on the socket directly */
116 
117 	if (lws_fi(&wsi->fic, "sendfail"))
118 		m = (unsigned int)LWS_SSL_CAPABLE_ERROR;
119 	else
120 		m = (unsigned int)lws_ssl_capable_write(wsi, buf, n);
121 
122 	lwsl_info("%s: ssl_capable_write (%d) says %d\n", __func__, n, m);
123 
124 	/* something got written, it can have been truncated now */
125 	wsi->could_have_pending = 1;
126 
127 	switch ((int)m) {
128 	case LWS_SSL_CAPABLE_ERROR:
129 		/* we're going to close, let close know sends aren't possible */
130 		wsi->socket_is_permanently_unusable = 1;
131 		return -1;
132 	case LWS_SSL_CAPABLE_MORE_SERVICE:
133 		/*
134 		 * nothing got sent, not fatal.  Retry the whole thing later,
135 		 * ie, implying treat it was a truncated send so it gets
136 		 * retried
137 		 */
138 		m = 0;
139 		break;
140 	}
141 
142 	if ((int)m < 0)
143 		m = 0;
144 
145 	/*
146 	 * we were sending this from buflist_out?  Then not sending everything
147 	 * is a small matter of advancing ourselves only by the amount we did
148 	 * send in the buflist.
149 	 */
150 	if (lws_has_buffered_out(wsi)) {
151 		if (m) {
152 			lwsl_info("%s partial adv %d (vs %ld)\n",
153 					lws_wsi_tag(wsi), m, (long)real_len);
154 			lws_buflist_use_segment(&wsi->buflist_out, m);
155 		}
156 
157 		if (!lws_has_buffered_out(wsi)) {
158 			lwsl_info("%s: %s: buflist_out flushed\n",
159 				  __func__, lws_wsi_tag(wsi));
160 
161 			m = (unsigned int)real_len;
162 			if (lwsi_state(wsi) == LRS_FLUSHING_BEFORE_CLOSE) {
163 				lwsl_info("*%s signalling to close now\n",
164 						lws_wsi_tag(wsi));
165 				return -1; /* retry closing now */
166 			}
167 
168 			if (wsi->close_when_buffered_out_drained) {
169 				wsi->close_when_buffered_out_drained = 0;
170 				return -1;
171 			}
172 
173 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
174 #if defined(LWS_WITH_SERVER)
175 			if (wsi->http.deferred_transaction_completed) {
176 				lwsl_notice("%s: partial completed, doing "
177 					    "deferred transaction completed\n",
178 					    __func__);
179 				wsi->http.deferred_transaction_completed = 0;
180 				return lws_http_transaction_completed(wsi) ?
181 							-1 : (int)real_len;
182 			}
183 #endif
184 #endif
185 #if defined(LWS_ROLE_WS)
186 			/* Since buflist_out flushed, we're not inside a frame any more */
187 			if (wsi->ws)
188 				wsi->ws->inside_frame = 0;
189 #endif
190 		}
191 		/* always callback on writeable */
192 		lws_callback_on_writable(wsi);
193 
194 		return (int)m;
195 	}
196 
197 #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
198 	if (wsi->http.comp_ctx.may_have_more)
199 		lws_callback_on_writable(wsi);
200 #endif
201 
202 	if (m == real_len)
203 		/* what we just sent went out cleanly */
204 		return (int)m;
205 
206 	/*
207 	 * We were not able to send everything... and we were not sending from
208 	 * an existing buflist_out.  So we are starting a fresh buflist_out, by
209 	 * buffering the unsent remainder on it.
210 	 * (it will get first priority next time the socket is writable).
211 	 */
212 	lwsl_debug("%s new partial sent %d from %lu total\n", lws_wsi_tag(wsi),
213 			m, (unsigned long)real_len);
214 
215 	if (lws_buflist_append_segment(&wsi->buflist_out, buf + m,
216 				       real_len - m) < 0)
217 		return -1;
218 
219 #if defined(LWS_WITH_UDP)
220 	if (lws_wsi_is_udp(wsi))
221 		/* stash original destination for fulfilling UDP partials */
222 		wsi->udp->sa46_pending = wsi->udp->sa46;
223 #endif
224 
225 	/* since something buffered, force it to get another chance to send */
226 	lws_callback_on_writable(wsi);
227 
228 	return (int)real_len;
229 }
230 
231 int
lws_write(struct lws * wsi,unsigned char * buf,size_t len,enum lws_write_protocol wp)232 lws_write(struct lws *wsi, unsigned char *buf, size_t len,
233 	  enum lws_write_protocol wp)
234 {
235 	int m;
236 
237 	if ((int)len < 0) {
238 		lwsl_err("%s: suspicious len int %d, ulong %lu\n", __func__,
239 				(int)len, (unsigned long)len);
240 		return -1;
241 	}
242 
243 #ifdef LWS_WITH_ACCESS_LOG
244 	wsi->http.access_log.sent += len;
245 #endif
246 
247 	assert(wsi->role_ops);
248 
249 	if (!lws_rops_fidx(wsi->role_ops, LWS_ROPS_write_role_protocol))
250 		m = lws_issue_raw(wsi, buf, len);
251 	else
252 		m = lws_rops_func_fidx(wsi->role_ops, LWS_ROPS_write_role_protocol).
253 				write_role_protocol(wsi, buf, len, &wp);
254 
255 #if defined(LWS_WITH_SYS_METRICS)
256 	if (wsi->a.vhost)
257 		lws_metric_event(wsi->a.vhost->mt_traffic_tx, (char)
258 				 (m < 0 ? METRES_NOGO : METRES_GO), len);
259 #endif
260 
261 	return m;
262 }
263 
264 int
lws_ssl_capable_read_no_ssl(struct lws * wsi,unsigned char * buf,size_t len)265 lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, size_t len)
266 {
267 	int n = 0, en;
268 
269 	errno = 0;
270 #if defined(LWS_WITH_UDP)
271 	if (lws_wsi_is_udp(wsi)) {
272 		socklen_t slt = sizeof(wsi->udp->sa46);
273 
274 		n = (int)recvfrom(wsi->desc.sockfd, (char *)buf,
275 #if defined(WIN32)
276 				(int)
277 #endif
278 				len, 0,
279 				sa46_sockaddr(&wsi->udp->sa46), &slt);
280 	} else
281 #endif
282 		n = (int)recv(wsi->desc.sockfd, (char *)buf,
283 #if defined(WIN32)
284 				(int)
285 #endif
286 				len, 0);
287 	en = LWS_ERRNO;
288 	if (n >= 0) {
289 
290 		if (!n && wsi->unix_skt)
291 			goto do_err;
292 
293 		/*
294 		 * See https://libwebsockets.org/
295 		 * pipermail/libwebsockets/2019-March/007857.html
296 		 */
297 		if (!n && !wsi->unix_skt)
298 			goto do_err;
299 
300 #if defined(LWS_WITH_SYS_METRICS) && defined(LWS_WITH_SERVER)
301 		if (wsi->a.vhost)
302 			lws_metric_event(wsi->a.vhost->mt_traffic_rx,
303 					 METRES_GO /* rx */, (unsigned int)n);
304 #endif
305 
306 		return n;
307 	}
308 
309 	if (en == LWS_EAGAIN ||
310 	    en == LWS_EWOULDBLOCK ||
311 	    en == LWS_EINTR)
312 		return LWS_SSL_CAPABLE_MORE_SERVICE;
313 
314 do_err:
315 #if defined(LWS_WITH_SYS_METRICS) && defined(LWS_WITH_SERVER)
316 	if (wsi->a.vhost)
317 		lws_metric_event(wsi->a.vhost->mt_traffic_rx, METRES_NOGO, 0u);
318 #endif
319 
320 	lwsl_info("%s: error on reading from skt : %d, errno %d\n",
321 			__func__, n, en);
322 
323 	return LWS_SSL_CAPABLE_ERROR;
324 }
325 
326 int
lws_ssl_capable_write_no_ssl(struct lws * wsi,unsigned char * buf,size_t len)327 lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, size_t len)
328 {
329 	int n = 0;
330 #if defined(LWS_PLAT_OPTEE)
331 	ssize_t send(int sockfd, const void *buf, size_t len, int flags);
332 #endif
333 
334 #if defined(LWS_WITH_UDP)
335 	if (lws_wsi_is_udp(wsi)) {
336 
337 		if (lws_fi(&wsi->fic, "udp_tx_loss")) {
338 			/* pretend it was sent */
339 			n = (int)(ssize_t)len;
340 			goto post_send;
341 		}
342 
343 		if (lws_has_buffered_out(wsi))
344 			n = (int)sendto(wsi->desc.sockfd, (const char *)buf,
345 #if defined(WIN32)
346 				(int)
347 #endif
348 				   len, 0, sa46_sockaddr(&wsi->udp->sa46_pending),
349 				   sa46_socklen(&wsi->udp->sa46_pending));
350 		else
351 			n = (int)sendto(wsi->desc.sockfd, (const char *)buf,
352 #if defined(WIN32)
353 				(int)
354 #endif
355 				   len, 0, sa46_sockaddr(&wsi->udp->sa46),
356 				   sa46_socklen(&wsi->udp->sa46));
357 	} else
358 #endif
359 		if (wsi->role_ops->file_handle)
360 			n = (int)write((int)(lws_intptr_t)wsi->desc.filefd, buf,
361 #if defined(WIN32)
362 				(int)
363 #endif
364 					len);
365 		else
366 			n = (int)send(wsi->desc.sockfd, (char *)buf,
367 #if defined(WIN32)
368 				(int)
369 #endif
370 					len, MSG_NOSIGNAL);
371 //	lwsl_info("%s: sent len %d result %d", __func__, len, n);
372 
373 #if defined(LWS_WITH_UDP)
374 post_send:
375 #endif
376 	if (n >= 0)
377 		return n;
378 
379 	if (LWS_ERRNO == LWS_EAGAIN ||
380 	    LWS_ERRNO == LWS_EWOULDBLOCK ||
381 	    LWS_ERRNO == LWS_EINTR) {
382 		if (LWS_ERRNO == LWS_EWOULDBLOCK) {
383 			lws_set_blocking_send(wsi);
384 		}
385 
386 		return LWS_SSL_CAPABLE_MORE_SERVICE;
387 	}
388 
389 	lwsl_debug("ERROR writing len %d to skt fd %d err %d / errno %d\n",
390 		   (int)(ssize_t)len, wsi->desc.sockfd, n, LWS_ERRNO);
391 
392 	return LWS_SSL_CAPABLE_ERROR;
393 }
394 
395 int
lws_ssl_pending_no_ssl(struct lws * wsi)396 lws_ssl_pending_no_ssl(struct lws *wsi)
397 {
398 	(void)wsi;
399 #if defined(LWS_PLAT_FREERTOS)
400 	return 100;
401 #else
402 	return 0;
403 #endif
404 }
405