Browse Source

Bump libwebsockets to version 2.4.2

Fabio Alessandrelli 7 years ago
parent
commit
262cb262eb

+ 1 - 1
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:

+ 14 - 6
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");

+ 1 - 1
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);

+ 7 - 4
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",

+ 2 - 5
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.

+ 16 - 20
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
 

+ 1 - 0
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;
 

+ 3 - 1
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 <stdlib.h>
 #else
 #include "malloc.h"
 #endif
+/* END GODOT ADDITION */
 
 void *ssl_mem_zalloc(size_t size);
 

+ 21 - 10
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;
 }

+ 38 - 3
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;

+ 1 - 1
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;
 				}

+ 1 - 1
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];

+ 8 - 2
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.

+ 6 - 1
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 ==

+ 1 - 4
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;

+ 1 - 1
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;
 	}

+ 16 - 1
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;

+ 5 - 4
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;