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