From 262cb262eb6c10c808dbbd85dd9103ab0f99c32b Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Sun, 18 Mar 2018 16:37:51 +0100 Subject: [PATCH] Bump libwebsockets to version 2.4.2 --- thirdparty/README.md | 2 +- thirdparty/lws/client/client.c | 20 ++++++--- thirdparty/lws/context.c | 2 +- thirdparty/lws/libwebsockets.c | 11 +++-- thirdparty/lws/libwebsockets.h | 7 +--- thirdparty/lws/lws_config.h | 36 ++++++++-------- .../include/internal/ssl_types.h | 1 + .../include/platform/ssl_port.h | 4 +- .../lws/mbedtls_wrapper/library/ssl_lib.c | 31 +++++++++----- .../lws/mbedtls_wrapper/platform/ssl_pm.c | 41 +++++++++++++++++-- thirdparty/lws/misc/lejp.c | 2 +- thirdparty/lws/misc/sha-1.c | 2 +- thirdparty/lws/output.c | 10 ++++- thirdparty/lws/pollfd.c | 7 +++- thirdparty/lws/private-libwebsockets.h | 5 +-- thirdparty/lws/server/ssl-server.c | 2 +- thirdparty/lws/service.c | 17 +++++++- thirdparty/lws/ssl.c | 9 ++-- 18 files changed, 143 insertions(+), 66 deletions(-) diff --git a/thirdparty/README.md b/thirdparty/README.md index d3fa0e46643..8f155efccc1 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -234,7 +234,7 @@ changes are marked with `// -- GODOT --` comments. ## libwebsockets - Upstream: https://github.com/warmcat/libwebsockets -- Version: 2.4.1 +- Version: 2.4.2 - License: LGPLv2.1 + static linking exception File extracted from upstream source: diff --git a/thirdparty/lws/client/client.c b/thirdparty/lws/client/client.c index 20450aa923c..ded4e4bf0b5 100644 --- a/thirdparty/lws/client/client.c +++ b/thirdparty/lws/client/client.c @@ -258,9 +258,10 @@ start_ws_handshake: #ifdef LWS_OPENSSL_SUPPORT /* we can retry this... just cook the SSL BIO the first time */ - if (wsi->use_ssl && !wsi->ssl) { - if (lws_ssl_client_bio_create(wsi)) - return -1; + if (wsi->use_ssl && !wsi->ssl && + lws_ssl_client_bio_create(wsi) < 0) { + cce = "bio_create failed"; + goto bail3; } if (wsi->use_ssl) { @@ -727,9 +728,10 @@ lws_client_interpret_server_handshake(struct lws *wsi) return 0; } - if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) { - lwsl_info("no ACCEPT\n"); - cce = "HS: ACCEPT missing"; + if (p && !strncmp(p, "401", 3)) { + lwsl_warn( + "lws_client_handshake: got bad HTTP response '%s'\n", p); + cce = "HS: ws upgrade unauthorized"; goto bail3; } @@ -740,6 +742,12 @@ lws_client_interpret_server_handshake(struct lws *wsi) goto bail3; } + if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) { + lwsl_info("no ACCEPT\n"); + cce = "HS: ACCEPT missing"; + goto bail3; + } + p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE); if (!p) { lwsl_info("no UPGRADE\n"); diff --git a/thirdparty/lws/context.c b/thirdparty/lws/context.c index f67476b1e3b..9f221f50f1f 100644 --- a/thirdparty/lws/context.c +++ b/thirdparty/lws/context.c @@ -1621,7 +1621,7 @@ lws_context_destroy2(struct lws_context *context) lws_check_deferred_free(context, 1); #if LWS_MAX_SMP > 1 - pthread_mutex_destroy(&context->lock, NULL); + pthread_mutex_destroy(&context->lock); #endif lws_free(context); diff --git a/thirdparty/lws/libwebsockets.c b/thirdparty/lws/libwebsockets.c index 50f975d21e7..8fe08540412 100644 --- a/thirdparty/lws/libwebsockets.c +++ b/thirdparty/lws/libwebsockets.c @@ -482,8 +482,9 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason) wsi->mode == LWSCM_WSCL_ISSUE_HANDSHAKE) goto just_kill_connection; - if (wsi->mode == LWSCM_HTTP_SERVING || - wsi->mode == LWSCM_HTTP2_SERVING) { + if (!wsi->told_user_closed && + (wsi->mode == LWSCM_HTTP_SERVING || + wsi->mode == LWSCM_HTTP2_SERVING)) { if (wsi->user_space) wsi->vhost->protocols->callback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL, @@ -583,7 +584,7 @@ just_kill_connection: lws_remove_child_from_any_parent(wsi); n = 0; - if (wsi->user_space) { + if (!wsi->told_user_closed && wsi->user_space) { lwsl_debug("%s: %p: DROP_PROTOCOL %s\n", __func__, wsi, wsi->protocol->name); wsi->protocol->callback(wsi, @@ -656,8 +657,10 @@ just_kill_connection: __func__, wsi, (int)(long)wsi->desc.sockfd, wsi->state); if (!wsi->socket_is_permanently_unusable && - lws_sockfd_valid(wsi->desc.sockfd)) + lws_sockfd_valid(wsi->desc.sockfd)) { + wsi->socket_is_permanently_unusable = 1; n = shutdown(wsi->desc.sockfd, SHUT_WR); + } } if (n) lwsl_debug("closing: shutdown (state %d) ret %d\n", diff --git a/thirdparty/lws/libwebsockets.h b/thirdparty/lws/libwebsockets.h index ef996c5d78b..460c732602e 100644 --- a/thirdparty/lws/libwebsockets.h +++ b/thirdparty/lws/libwebsockets.h @@ -1073,7 +1073,7 @@ enum lws_callback_reasons { LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS = 22, /**< if configured for * including OpenSSL support, this callback allows your user code - * to load extra certifcates into the server which allow it to + * to load extra certificates into the server which allow it to * verify the validity of certificates returned by clients. user * is the server's OpenSSL SSL_CTX* */ LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION = 23, @@ -4013,9 +4013,6 @@ lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); #if !defined(LWS_SIZEOFPTR) #define LWS_SIZEOFPTR (sizeof (void *)) #endif -#if !defined(u_int64_t) -#define u_int64_t unsigned long long -#endif #if defined(__x86_64__) #define _LWS_PAD_SIZE 16 /* Intel recommended for best performance */ @@ -4808,7 +4805,7 @@ LWS_VISIBLE LWS_EXTERN unsigned long lws_now_secs(void); /** - * lws_get_context - Allow geting lws_context from a Websocket connection + * lws_get_context - Allow getting lws_context from a Websocket connection * instance * * With this function, users can access context in the callback function. diff --git a/thirdparty/lws/lws_config.h b/thirdparty/lws/lws_config.h index 3a918747b1f..6005d94ec6c 100644 --- a/thirdparty/lws/lws_config.h +++ b/thirdparty/lws/lws_config.h @@ -1,5 +1,10 @@ /* lws_config.h Generated from lws_config.h.in */ -#include "lws_config_private.h" + +/* GODOT ADDITION */ +#ifndef DEBUG_ENABLED +#define LWS_WITH_NO_LOGS +#endif +/* END GODOT ADDITION */ #ifndef NDEBUG #ifndef _DEBUG @@ -25,54 +30,45 @@ /* #undef LWS_WITH_PLUGINS */ /* #undef LWS_WITH_NO_LOGS */ -#ifndef DEBUG_ENABLED -#define LWS_WITH_NO_LOGS -#endif /* The Libwebsocket version */ -#define LWS_LIBRARY_VERSION "2.4.1" +#define LWS_LIBRARY_VERSION "2.4.2" #define LWS_LIBRARY_VERSION_MAJOR 2 #define LWS_LIBRARY_VERSION_MINOR 4 -#define LWS_LIBRARY_VERSION_PATCH 1 +#define LWS_LIBRARY_VERSION_PATCH 2 /* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */ #define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR*1000000)+(LWS_LIBRARY_VERSION_MINOR*1000)+LWS_LIBRARY_VERSION_PATCH /* The current git commit hash that we're building from */ -#define LWS_BUILD_HASH "55f97b7806e07db2d4c8a158172cd309d0faf450" +#define LWS_BUILD_HASH "8964ce9db75a98e463dfafd2e89f2bc8a95ec6ed" /* Build with OpenSSL support */ #define LWS_OPENSSL_SUPPORT /* The client should load and trust CA root certs it finds in the OS */ -#define LWS_SSL_CLIENT_USE_OS_CA_CERTS +/* #undef LWS_SSL_CLIENT_USE_OS_CA_CERTS */ /* Sets the path where the client certs should be installed. */ -#define LWS_OPENSSL_CLIENT_CERTS "../share" +/* #undef LWS_OPENSSL_CLIENT_CERTS "../share" */ /* Turn off websocket extensions */ /* #undef LWS_NO_EXTENSIONS */ /* Enable libev io loop */ /* #undef LWS_WITH_LIBEV */ -#undef LWS_WITH_LIBEV /* Enable libuv io loop */ /* #undef LWS_WITH_LIBUV */ -#undef LWS_WITH_LIBUV /* Enable libevent io loop */ /* #undef LWS_WITH_LIBEVENT */ -#undef LWS_WITH_LIBEVENT /* Build with support for ipv6 */ /* #undef LWS_WITH_IPV6 */ /* Build with support for UNIX domain socket */ /* #undef LWS_WITH_UNIX_SOCK */ -#ifdef WINDOWS_ENABLED -#undef LWS_USE_UNIX_SOCK -#endif /* Build with support for HTTP2 */ /* #undef LWS_WITH_HTTP2 */ @@ -100,7 +96,7 @@ /* SSL server using ECDH certificate */ /* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */ -#define LWS_HAVE_SSL_CTX_set1_param +/* #undef LWS_HAVE_SSL_CTX_set1_param */ #define LWS_HAVE_X509_VERIFY_PARAM_set1_host /* #undef LWS_HAVE_RSA_SET0_KEY */ @@ -110,7 +106,7 @@ /* #undef LWS_WITH_CGI */ /* whether the Openssl is recent enough, and / or built with, ecdh */ -#define LWS_HAVE_OPENSSL_ECDH_H +/* #undef LWS_HAVE_OPENSSL_ECDH_H */ /* HTTP Proxy support */ /* #undef LWS_WITH_HTTP_PROXY */ @@ -157,9 +153,9 @@ /* OpenSSL various APIs */ -/* #undef LWS_HAVE_TLS_CLIENT_METHOD */ -#define LWS_HAVE_TLSV1_2_CLIENT_METHOD -#define LWS_HAVE_SSL_SET_INFO_CALLBACK +#define LWS_HAVE_TLS_CLIENT_METHOD +/* #undef LWS_HAVE_TLSV1_2_CLIENT_METHOD */ +/* #undef LWS_HAVE_SSL_SET_INFO_CALLBACK */ #define LWS_HAS_INTPTR_T diff --git a/thirdparty/lws/mbedtls_wrapper/include/internal/ssl_types.h b/thirdparty/lws/mbedtls_wrapper/include/internal/ssl_types.h index 45198bc9786..2ca438c422d 100644 --- a/thirdparty/lws/mbedtls_wrapper/include/internal/ssl_types.h +++ b/thirdparty/lws/mbedtls_wrapper/include/internal/ssl_types.h @@ -215,6 +215,7 @@ struct ssl_st int (*verify_callback) (int ok, X509_STORE_CTX *ctx); int rwstate; + int interrupted_remaining_write; long verify_result; diff --git a/thirdparty/lws/mbedtls_wrapper/include/platform/ssl_port.h b/thirdparty/lws/mbedtls_wrapper/include/platform/ssl_port.h index 2ffd7e75442..eca68f20d12 100644 --- a/thirdparty/lws/mbedtls_wrapper/include/platform/ssl_port.h +++ b/thirdparty/lws/mbedtls_wrapper/include/platform/ssl_port.h @@ -25,11 +25,13 @@ */ #include "string.h" -#if defined(__APPLE__) || defined(__FreeBSD__) +/* GODOT ADDITION */ +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) #include #else #include "malloc.h" #endif +/* END GODOT ADDITION */ void *ssl_mem_zalloc(size_t size); diff --git a/thirdparty/lws/mbedtls_wrapper/library/ssl_lib.c b/thirdparty/lws/mbedtls_wrapper/library/ssl_lib.c index 187fc9f005e..d8fdd06fade 100644 --- a/thirdparty/lws/mbedtls_wrapper/library/ssl_lib.c +++ b/thirdparty/lws/mbedtls_wrapper/library/ssl_lib.c @@ -142,9 +142,9 @@ int SSL_get_error(const SSL *ssl, int ret_code) ret = SSL_ERROR_NONE; else if (ret_code < 0) { - if (SSL_want_read(ssl)) + if (ssl->err == SSL_ERROR_WANT_READ || SSL_want_read(ssl)) ret = SSL_ERROR_WANT_READ; - else if (SSL_want_write(ssl)) + else if (ssl->err == SSL_ERROR_WANT_WRITE || SSL_want_write(ssl)) ret = SSL_ERROR_WANT_WRITE; else ret = SSL_ERROR_SYSCALL; //unknown @@ -457,7 +457,7 @@ int SSL_read(SSL *ssl, void *buffer, int len) int SSL_write(SSL *ssl, const void *buffer, int len) { int ret; - int send_bytes; + int send_bytes, bytes; const unsigned char *pbuf; SSL_ASSERT1(ssl); @@ -470,25 +470,36 @@ int SSL_write(SSL *ssl, const void *buffer, int len) pbuf = (const unsigned char *)buffer; do { - int bytes; - if (send_bytes > SSL_SEND_DATA_MAX_LENGTH) bytes = SSL_SEND_DATA_MAX_LENGTH; else bytes = send_bytes; + if (ssl->interrupted_remaining_write) { + bytes = ssl->interrupted_remaining_write; + ssl->interrupted_remaining_write = 0; + } + ret = SSL_METHOD_CALL(send, ssl, pbuf, bytes); + //printf("%s: ssl_pm said %d for %d requested (cum %d)\n", __func__, ret, bytes, len -send_bytes); + /* the return is a NEGATIVE OpenSSL error code, or the length sent */ if (ret > 0) { pbuf += ret; send_bytes -= ret; - } - } while (ret > 0 && send_bytes); + } else + ssl->interrupted_remaining_write = bytes; + } while (ret > 0 && send_bytes && ret == bytes); if (ret >= 0) { ret = len - send_bytes; - ssl->rwstate = SSL_NOTHING; - } else - ret = -1; + if (!ret) + ssl->rwstate = SSL_NOTHING; + } else { + if (send_bytes == len) + ret = -1; + else + ret = len - send_bytes; + } return ret; } diff --git a/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c b/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c index 536733fbaba..63504919ce4 100644 --- a/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c +++ b/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c @@ -360,17 +360,52 @@ int ssl_pm_read(SSL *ssl, void *buffer, int len) return ret; } +/* + * This returns -1, or the length sent. + * If -1, then you need to find out if the error was + * fatal or recoverable using SSL_get_error() + */ int ssl_pm_send(SSL *ssl, const void *buffer, int len) { int ret; struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len); + /* + * We can get a positive number, which may be less than len... that + * much was sent successfully and you can call again to send more. + * + * We can get a negative mbedtls error code... if WANT_WRITE or WANT_READ, + * it's nonfatal and means it should be retried as-is. If something else, + * it's fatal actually. + * + * If this function returns something other than a positive value or + * MBEDTLS_ERR_SSL_WANT_READ/WRITE, the ssl context becomes unusable, and + * you should either free it or call mbedtls_ssl_session_reset() on it + * before re-using it for a new connection; the current connection must + * be closed. + * + * When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, it must be + * called later with the same arguments, until it returns a positive value. + */ + if (ret < 0) { - if (ret == MBEDTLS_ERR_NET_CONN_RESET) + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_write() return -0x%x", -ret); + switch (ret) { + case MBEDTLS_ERR_NET_CONN_RESET: ssl->err = SSL_ERROR_SYSCALL; - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_write() return -0x%x", -ret); - ret = -1; + break; + case MBEDTLS_ERR_SSL_WANT_WRITE: + ssl->err = SSL_ERROR_WANT_WRITE; + break; + case MBEDTLS_ERR_SSL_WANT_READ: + ssl->err = SSL_ERROR_WANT_READ; + break; + default: + break; + } + + ret = -1; } return ret; diff --git a/thirdparty/lws/misc/lejp.c b/thirdparty/lws/misc/lejp.c index 5407c90f97b..38efa8b1226 100644 --- a/thirdparty/lws/misc/lejp.c +++ b/thirdparty/lws/misc/lejp.c @@ -444,7 +444,7 @@ lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len) goto append_npos; } if (c == '.') { - if (ctx->dcount || (ctx->f & LEJP_SEEN_POINT)) { + if (!ctx->dcount || (ctx->f & LEJP_SEEN_POINT)) { ret = LEJP_REJECT_MP_VAL_NUM_FORMAT; goto reject; } diff --git a/thirdparty/lws/misc/sha-1.c b/thirdparty/lws/misc/sha-1.c index 9353fbefe41..50205a0100b 100644 --- a/thirdparty/lws/misc/sha-1.c +++ b/thirdparty/lws/misc/sha-1.c @@ -45,7 +45,7 @@ struct sha1_ctxt { } h; union { unsigned char b8[8]; - u_int64_t b64[1]; + uint64_t b64[1]; } c; union { unsigned char b8[64]; diff --git a/thirdparty/lws/output.c b/thirdparty/lws/output.c index ed4752490e3..375ff3ef995 100644 --- a/thirdparty/lws/output.c +++ b/thirdparty/lws/output.c @@ -270,9 +270,12 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len, if (wsi->state != LWSS_ESTABLISHED && ((wsi->state != LWSS_RETURNED_CLOSE_ALREADY && + wsi->state != LWSS_WAITING_TO_SEND_CLOSE_NOTIFICATION && wsi->state != LWSS_AWAITING_CLOSE_ACK) || - wp != LWS_WRITE_CLOSE)) + wp != LWS_WRITE_CLOSE)) { + lwsl_debug("binning\n"); return 0; + } /* if we are continuing a frame that already had its header done */ @@ -507,7 +510,7 @@ send_raw: (wp & 0x1f) == LWS_WRITE_HTTP_FINAL) && wsi->u.http.tx_content_length) { wsi->u.http.tx_content_remain -= len; - lwsl_info("%s: content_remain = %llu\n", __func__, + lwsl_info("%s: wsi %p: tx_content_remain = %llu\n", __func__, wsi, (unsigned long long)wsi->u.http.tx_content_remain); if (!wsi->u.http.tx_content_remain) { lwsl_info("%s: selecting final write mode\n", __func__); @@ -639,6 +642,9 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) poss = context->pt_serv_buf_size - n - LWS_H2_FRAME_HEADER_LENGTH; + if (poss > wsi->u.http.tx_content_remain) + poss = wsi->u.http.tx_content_remain; + /* * if there is a hint about how much we will do well to send at one time, * restrict ourselves to only trying to send that. diff --git a/thirdparty/lws/pollfd.c b/thirdparty/lws/pollfd.c index 4d6704d41cc..54a4a860571 100644 --- a/thirdparty/lws/pollfd.c +++ b/thirdparty/lws/pollfd.c @@ -537,9 +537,14 @@ LWS_VISIBLE int lws_callback_on_writable_all_protocol(const struct lws_context *context, const struct lws_protocols *protocol) { - struct lws_vhost *vhost = context->vhost_list; + struct lws_vhost *vhost; int n; + if (!context) + return 0; + + vhost = context->vhost_list; + while (vhost) { for (n = 0; n < vhost->count_protocols; n++) if (protocol->callback == diff --git a/thirdparty/lws/private-libwebsockets.h b/thirdparty/lws/private-libwebsockets.h index 4f0b3743326..535fa0be579 100644 --- a/thirdparty/lws/private-libwebsockets.h +++ b/thirdparty/lws/private-libwebsockets.h @@ -356,9 +356,6 @@ esp8266_tcp_stream_bind(lws_sockfd_type fd, int port, struct lws *wsi); #ifndef BYTE_ORDER #define BYTE_ORDER LITTLE_ENDIAN #endif -#ifndef u_int64_t -typedef unsigned __int64 u_int64_t; -#endif #undef __P #ifndef __P @@ -1633,7 +1630,6 @@ struct lws_h2_netconn { unsigned int pad_length:1; unsigned int collected_priority:1; unsigned int is_first_header_char:1; - unsigned int seen_nonpseudoheader:1; unsigned int zero_huff_padding:1; unsigned int last_action_dyntable_resize:1; @@ -1922,6 +1918,7 @@ struct lws { unsigned int hdr_parsing_completed:1; unsigned int http2_substream:1; unsigned int upgraded_to_http2:1; + unsigned int seen_nonpseudoheader:1; unsigned int listener:1; unsigned int user_space_externally_allocated:1; unsigned int socket_is_permanently_unusable:1; diff --git a/thirdparty/lws/server/ssl-server.c b/thirdparty/lws/server/ssl-server.c index a9516f2239d..c4362824bfd 100644 --- a/thirdparty/lws/server/ssl-server.c +++ b/thirdparty/lws/server/ssl-server.c @@ -155,7 +155,7 @@ lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg) */ vh = context->vhost_list; while (vh) { - if (!vh->being_destroyed && vh->ssl_ctx == SSL_get_SSL_CTX(ssl)) + if (!vh->being_destroyed && ssl && vh->ssl_ctx == SSL_get_SSL_CTX(ssl)) break; vh = vh->vhost_next; } diff --git a/thirdparty/lws/service.c b/thirdparty/lws/service.c index 6748e30bd4a..8cf455e2c9f 100644 --- a/thirdparty/lws/service.c +++ b/thirdparty/lws/service.c @@ -1073,6 +1073,8 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t c = lws_token_to_string(m); if (!c) break; + if (!(*c)) + break; len = lws_hdr_total_length(wsi, m); if (!len || len > sizeof(buf) - 1) { @@ -1090,6 +1092,11 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t m++; } while (1); + /* explicitly detach the ah */ + + lws_header_table_force_to_detachable_state(wsi); + lws_header_table_detach(wsi, 0); + /* ... and then drop the connection */ if (wsi->desc.sockfd == our_fd) @@ -1098,7 +1105,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS); - ah = ah->next; + ah = pt->ah_list; } #ifdef LWS_WITH_CGI @@ -1644,6 +1651,14 @@ drain: break; } #endif + /* + * something went wrong with parsing the handshake, and + * we ended up back in the event loop without completing it + */ + case LWSCM_PRE_WS_SERVING_ACCEPT: + wsi->socket_is_permanently_unusable = 1; + goto close_and_handled; + default: #ifdef LWS_NO_CLIENT break; diff --git a/thirdparty/lws/ssl.c b/thirdparty/lws/ssl.c index 0a647b469ca..755d06db415 100644 --- a/thirdparty/lws/ssl.c +++ b/thirdparty/lws/ssl.c @@ -463,7 +463,7 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len) lwsl_debug("%p: SSL_read says %d\n", wsi, n); /* manpage: returning 0 means connection shut down */ - if (!n) { + if (!n || (n == -1 && errno == ENOTCONN)) { wsi->socket_is_permanently_unusable = 1; return LWS_SSL_CAPABLE_ERROR; @@ -476,12 +476,12 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len) m == SSL_ERROR_SYSCALL) return LWS_SSL_CAPABLE_ERROR; - if (SSL_want_read(wsi->ssl)) { + if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->ssl)) { lwsl_debug("%s: WANT_READ\n", __func__); lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi); return LWS_SSL_CAPABLE_MORE_SERVICE; } - if (SSL_want_write(wsi->ssl)) { + if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl)) { lwsl_debug("%s: WANT_WRITE\n", __func__); lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi); return LWS_SSL_CAPABLE_MORE_SERVICE; @@ -885,6 +885,7 @@ go_again: failed: lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_SSL_CONNECTIONS_FAILED, 1); + wsi->socket_is_permanently_unusable = 1; lwsl_info("SSL_accept failed socket %u: %s\n", wsi->desc.sockfd, lws_ssl_get_error_string(m, n, buf, sizeof(buf))); lws_ssl_elaborate_error(); @@ -903,7 +904,7 @@ accepted: /* adapt our vhost to match the SNI SSL_CTX that was chosen */ vh = context->vhost_list; while (vh) { - if (!vh->being_destroyed && + if (!vh->being_destroyed && wsi->ssl && vh->ssl_ctx == SSL_get_SSL_CTX(wsi->ssl)) { lwsl_info("setting wsi to vh %s\n", vh->name); wsi->vhost = vh;