Bump libwebsockets to version 2.4.2

This commit is contained in:
Fabio Alessandrelli 2018-03-18 16:37:51 +01:00
parent 9ad1800298
commit 262cb262eb
18 changed files with 143 additions and 66 deletions

View file

@ -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:

View file

@ -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");

View file

@ -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);

View file

@ -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",

View file

@ -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.

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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];

View file

@ -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.

View file

@ -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 ==

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;