mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
ah pool: change to dynamic linked list
For some targets like ESP32, the ah pool is mainly sitting idle wasting memory. For HTTP/2, if the client sends a series of pipelined headers on different SIDs that exist simultaneously, there is no way to stall the headers to wait for an ah, because we must read the stream for stuff like WINDOW_UPDATE on the other streams. In both these cases having the ability to free unused ah completely and allocate more dynamically if there is memory is useful, so this patch makes the ah pool an initially-empty linked list that allocates on demand up to the "max pool size" limit from the context info. When nobody wants an ah, it is freed (if someone was waiting for it, it is directly reused). For ESP32 it means no large, permanent alloc when lws starts and dynamic alloc according to how many streams the client opens, which can be controlled by SETTINGS.
This commit is contained in:
parent
4f99ccd6a8
commit
9c2a7dd58b
9 changed files with 183 additions and 122 deletions
|
@ -757,7 +757,7 @@ lws_create_context(struct lws_context_creation_info *info)
|
|||
#ifndef LWS_NO_DAEMONIZE
|
||||
int pid_daemon = get_daemonize_pid();
|
||||
#endif
|
||||
int n, m;
|
||||
int n;
|
||||
#if defined(__ANDROID__)
|
||||
struct rlimit rt;
|
||||
#endif
|
||||
|
@ -908,7 +908,8 @@ lws_create_context(struct lws_context_creation_info *info)
|
|||
* and header data pool
|
||||
*/
|
||||
for (n = 0; n < context->count_threads; n++) {
|
||||
context->pt[n].serv_buf = lws_zalloc(context->pt_serv_buf_size, "pt_serv_buf");
|
||||
context->pt[n].serv_buf = lws_malloc(context->pt_serv_buf_size,
|
||||
"pt_serv_buf");
|
||||
if (!context->pt[n].serv_buf) {
|
||||
lwsl_err("OOM\n");
|
||||
return NULL;
|
||||
|
@ -918,19 +919,8 @@ lws_create_context(struct lws_context_creation_info *info)
|
|||
context->pt[n].context = context;
|
||||
#endif
|
||||
context->pt[n].tid = n;
|
||||
context->pt[n].http_header_data = lws_malloc(context->max_http_header_data *
|
||||
context->max_http_header_pool, "context ah hdr data");
|
||||
if (!context->pt[n].http_header_data)
|
||||
goto bail;
|
||||
|
||||
context->pt[n].ah_pool = lws_zalloc(sizeof(struct allocated_headers) *
|
||||
context->max_http_header_pool, "context ah hdr pool");
|
||||
for (m = 0; m < context->max_http_header_pool; m++)
|
||||
context->pt[n].ah_pool[m].data =
|
||||
(char *)context->pt[n].http_header_data +
|
||||
(m * context->max_http_header_data);
|
||||
if (!context->pt[n].ah_pool)
|
||||
goto bail;
|
||||
context->pt[n].ah_list = NULL;
|
||||
context->pt[n].ah_pool_length = 0;
|
||||
|
||||
lws_pt_mutex_init(&context->pt[n]);
|
||||
}
|
||||
|
@ -1457,10 +1447,9 @@ lws_context_destroy(struct lws_context *context)
|
|||
lws_libevent_destroyloop(context, n);
|
||||
|
||||
lws_free_set_NULL(context->pt[n].serv_buf);
|
||||
if (pt->ah_pool)
|
||||
lws_free(pt->ah_pool);
|
||||
if (pt->http_header_data)
|
||||
lws_free(pt->http_header_data);
|
||||
|
||||
while (pt->ah_list)
|
||||
_lws_destroy_ah(pt, pt->ah_list);
|
||||
}
|
||||
lws_plat_context_early_destroy(context);
|
||||
|
||||
|
|
|
@ -289,11 +289,11 @@ lws_hpack_add_dynamic_header(struct lws *wsi, int token, char *arg, int len)
|
|||
return 1;
|
||||
wsi->u.http2.hpack_dyn_table = dyn;
|
||||
|
||||
dyn->args = lws_malloc(1024);
|
||||
dyn->args = lws_malloc(1024, "hpack");
|
||||
if (!dyn->args)
|
||||
goto bail1;
|
||||
dyn->args_length = 1024;
|
||||
dyn->entries = lws_malloc(sizeof(dyn->entries[0]) * 20);
|
||||
dyn->entries = lws_malloc(sizeof(dyn->entries[0]) * 20, "hpack dyn entries");
|
||||
if (!dyn->entries)
|
||||
goto bail2;
|
||||
dyn->num_entries = 20;
|
||||
|
|
|
@ -66,7 +66,7 @@ void
|
|||
lws_free_wsi(struct lws *wsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt;
|
||||
int n;
|
||||
struct allocated_headers *ah;
|
||||
|
||||
if (!wsi)
|
||||
return;
|
||||
|
@ -94,14 +94,16 @@ lws_free_wsi(struct lws *wsi)
|
|||
wsi->vhost->lserv_wsi = NULL;
|
||||
|
||||
lws_pt_lock(pt);
|
||||
for (n = 0; n < wsi->context->max_http_header_pool; n++) {
|
||||
if (pt->ah_pool[n].in_use &&
|
||||
pt->ah_pool[n].wsi == wsi) {
|
||||
ah = pt->ah_list;
|
||||
while (ah) {
|
||||
if (ah->in_use && ah->wsi == wsi) {
|
||||
lwsl_err("%s: ah leak: wsi %p\n", __func__, wsi);
|
||||
pt->ah_pool[n].in_use = 0;
|
||||
pt->ah_pool[n].wsi = NULL;
|
||||
ah->in_use = 0;
|
||||
ah->wsi = NULL;
|
||||
pt->ah_count_in_use--;
|
||||
break;
|
||||
}
|
||||
ah = ah->next;
|
||||
}
|
||||
|
||||
#if defined(LWS_WITH_PEER_LIMITS)
|
||||
|
|
|
@ -60,6 +60,51 @@ lextable_decode(int pos, char c)
|
|||
}
|
||||
}
|
||||
|
||||
static struct allocated_headers *
|
||||
_lws_create_ah(struct lws_context_per_thread *pt, ah_data_idx_t data_size)
|
||||
{
|
||||
struct allocated_headers *ah = lws_zalloc(sizeof(*ah), "ah struct");
|
||||
|
||||
if (!ah)
|
||||
return NULL;
|
||||
|
||||
ah->data = lws_malloc(data_size, "ah data");
|
||||
if (!ah->data) {
|
||||
lws_free(ah);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
ah->next = pt->ah_list;
|
||||
pt->ah_list = ah;
|
||||
ah->data_length = data_size;
|
||||
pt->ah_pool_length++;
|
||||
|
||||
lwsl_info("%s: created ah %p (size %d): pool length %d\n", __func__,
|
||||
ah, (int)data_size, pt->ah_pool_length);
|
||||
|
||||
return ah;
|
||||
}
|
||||
|
||||
int
|
||||
_lws_destroy_ah(struct lws_context_per_thread *pt, struct allocated_headers *ah)
|
||||
{
|
||||
lws_start_foreach_llp(struct allocated_headers **, a, pt->ah_list) {
|
||||
if ((*a) == ah) {
|
||||
*a = ah->next;
|
||||
pt->ah_pool_length--;
|
||||
lwsl_info("%s: freed ah %p : pool length %d\n",
|
||||
__func__, ah, pt->ah_pool_length);
|
||||
if (ah->data)
|
||||
lws_free(ah->data);
|
||||
lws_free(ah);
|
||||
|
||||
return 0;
|
||||
}
|
||||
} lws_end_foreach_llp(a, next);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
_lws_header_table_reset(struct allocated_headers *ah)
|
||||
{
|
||||
|
@ -214,16 +259,15 @@ lws_header_table_attach(struct lws *wsi, int autoservice)
|
|||
|
||||
__lws_remove_from_ah_waiting_list(wsi);
|
||||
|
||||
for (n = 0; n < context->max_http_header_pool; n++)
|
||||
if (!pt->ah_pool[n].in_use)
|
||||
break;
|
||||
wsi->u.hdr.ah = _lws_create_ah(pt, context->max_http_header_data);
|
||||
if (!wsi->u.hdr.ah) { /* we could not create an ah */
|
||||
_lws_header_ensure_we_are_on_waiting_list(wsi);
|
||||
|
||||
/* if the count of in use said something free... */
|
||||
assert(n != context->max_http_header_pool);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
wsi->u.hdr.ah = &pt->ah_pool[n];
|
||||
wsi->u.hdr.ah->in_use = 1;
|
||||
pt->ah_pool[n].wsi = wsi; /* mark our owner */
|
||||
wsi->u.hdr.ah->wsi = wsi; /* mark our owner */
|
||||
pt->ah_count_in_use++;
|
||||
|
||||
#if defined(LWS_WITH_PEER_LIMITS)
|
||||
|
@ -431,7 +475,7 @@ bail:
|
|||
|
||||
nobody_usable_waiting:
|
||||
lwsl_info("%s: nobody usable waiting\n", __func__);
|
||||
ah->in_use = 0;
|
||||
_lws_destroy_ah(pt, ah);
|
||||
pt->ah_count_in_use--;
|
||||
|
||||
goto bail;
|
||||
|
|
|
@ -731,10 +731,17 @@ struct lws_fd_hashtable {
|
|||
* other APIs to get information out of it.
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_ESP32)
|
||||
typedef uint16_t ah_data_idx_t;
|
||||
#else
|
||||
typedef uint32_t ah_data_idx_t;
|
||||
#endif
|
||||
|
||||
struct lws_fragments {
|
||||
unsigned int offset;
|
||||
unsigned short len;
|
||||
unsigned char nfrag; /* which ah->frag[] continues this content, or 0 */
|
||||
ah_data_idx_t offset;
|
||||
uint16_t len;
|
||||
uint8_t nfrag; /* which ah->frag[] continues this content, or 0 */
|
||||
uint8_t flags; /* only http2 cares */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -743,34 +750,39 @@ struct lws_fragments {
|
|||
*/
|
||||
|
||||
struct allocated_headers {
|
||||
struct allocated_headers *next; /* linked list */
|
||||
struct lws *wsi; /* owner */
|
||||
char *data; /* prepared by context init to point to dedicated storage */
|
||||
ah_data_idx_t data_length;
|
||||
/*
|
||||
* the randomly ordered fragments, indexed by frag_index and
|
||||
* lws_fragments->nfrag for continuation.
|
||||
*/
|
||||
struct lws_fragments frags[WSI_TOKEN_COUNT * 2];
|
||||
struct lws_fragments frags[WSI_TOKEN_COUNT];
|
||||
time_t assigned;
|
||||
/*
|
||||
* for each recognized token, frag_index says which frag[] his data
|
||||
* starts in (0 means the token did not appear)
|
||||
* the actual header data gets dumped as it comes in, into data[]
|
||||
*/
|
||||
unsigned char frag_index[WSI_TOKEN_COUNT];
|
||||
unsigned char rx[2048];
|
||||
uint8_t frag_index[WSI_TOKEN_COUNT];
|
||||
#if defined(LWS_WITH_ESP32)
|
||||
uint8_t rx[256];
|
||||
#else
|
||||
uint8_t rx[2048];
|
||||
#endif
|
||||
|
||||
unsigned int rxpos;
|
||||
unsigned int rxlen;
|
||||
unsigned int pos;
|
||||
|
||||
unsigned int http_response;
|
||||
int16_t rxpos;
|
||||
int16_t rxlen;
|
||||
uint32_t pos;
|
||||
uint32_t http_response;
|
||||
|
||||
#ifndef LWS_NO_CLIENT
|
||||
char initial_handshake_hash_base64[30];
|
||||
#endif
|
||||
|
||||
unsigned char in_use;
|
||||
unsigned char nfrag;
|
||||
uint8_t in_use;
|
||||
uint8_t nfrag;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -796,7 +808,7 @@ struct lws_context_per_thread {
|
|||
struct lws_cgi *cgi_list;
|
||||
#endif
|
||||
void *http_header_data;
|
||||
struct allocated_headers *ah_pool;
|
||||
struct allocated_headers *ah_list;
|
||||
struct lws *ah_wait_list;
|
||||
int ah_wait_list_length;
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
|
@ -835,6 +847,7 @@ struct lws_context_per_thread {
|
|||
lws_sockfd_type dummy_pipe_fds[2];
|
||||
#endif
|
||||
unsigned int fds_count;
|
||||
uint32_t ah_pool_length;
|
||||
|
||||
short ah_count_in_use;
|
||||
unsigned char tid;
|
||||
|
@ -1901,6 +1914,9 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd);
|
|||
LWS_EXTERN struct lws *
|
||||
lws_client_connect_via_info2(struct lws *wsi);
|
||||
|
||||
LWS_EXTERN int
|
||||
_lws_destroy_ah(struct lws_context_per_thread *pt, struct allocated_headers *ah);
|
||||
|
||||
/*
|
||||
* EXTENSIONS
|
||||
*/
|
||||
|
|
146
lib/service.c
146
lib/service.c
|
@ -73,7 +73,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
|
|||
int write_type = LWS_WRITE_PONG;
|
||||
struct lws_tokens eff_buf;
|
||||
#ifdef LWS_WITH_HTTP2
|
||||
struct lws *wsi2, *wsi2a;
|
||||
struct lws *wsi2;
|
||||
#endif
|
||||
int ret, m, n;
|
||||
|
||||
|
@ -530,7 +530,7 @@ LWS_VISIBLE LWS_EXTERN int
|
|||
lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int tsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
int n;
|
||||
struct allocated_headers *ah;
|
||||
|
||||
/* Figure out if we really want to wait in poll()
|
||||
* We only need to wait if really nothing already to do and we have
|
||||
|
@ -550,15 +550,16 @@ lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int tsi)
|
|||
#endif
|
||||
|
||||
/* 3) if any ah has pending rx, do not wait in poll */
|
||||
for (n = 0; n < context->max_http_header_pool; n++)
|
||||
if (pt->ah_pool[n].rxpos != pt->ah_pool[n].rxlen) {
|
||||
/* any ah with pending rx must be attached to someone */
|
||||
if (!pt->ah_pool[n].wsi) {
|
||||
lwsl_err("%s: ah with no wsi\n", __func__);
|
||||
ah = pt->ah_list;
|
||||
while (ah) {
|
||||
if (ah->rxpos != ah->rxlen) {
|
||||
if (!ah->wsi) {
|
||||
assert(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ah = ah->next;
|
||||
}
|
||||
|
||||
return timeout_ms;
|
||||
}
|
||||
|
@ -573,12 +574,12 @@ int
|
|||
lws_service_flag_pending(struct lws_context *context, int tsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
struct allocated_headers *ah;
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
struct lws *wsi_next;
|
||||
#endif
|
||||
struct lws *wsi;
|
||||
int forced = 0;
|
||||
int n;
|
||||
|
||||
/* POLLIN faking */
|
||||
|
||||
|
@ -629,16 +630,20 @@ lws_service_flag_pending(struct lws_context *context, int tsi)
|
|||
* fake their POLLIN status so they will be able to drain the
|
||||
* rx buffered in the ah
|
||||
*/
|
||||
for (n = 0; n < context->max_http_header_pool; n++)
|
||||
if (pt->ah_pool[n].rxpos != pt->ah_pool[n].rxlen &&
|
||||
!pt->ah_pool[n].wsi->hdr_parsing_completed) {
|
||||
pt->fds[pt->ah_pool[n].wsi->position_in_fds_table].revents |=
|
||||
pt->fds[pt->ah_pool[n].wsi->position_in_fds_table].events &
|
||||
ah = pt->ah_list;
|
||||
while (ah) {
|
||||
if (ah->rxpos != ah->rxlen && !ah->wsi->hdr_parsing_completed) {
|
||||
pt->fds[ah->wsi->position_in_fds_table].revents |=
|
||||
pt->fds[ah->wsi->position_in_fds_table].events &
|
||||
LWS_POLLIN;
|
||||
if (pt->fds[pt->ah_pool[n].wsi->position_in_fds_table].revents &
|
||||
LWS_POLLIN)
|
||||
if (pt->fds[ah->wsi->position_in_fds_table].revents &
|
||||
LWS_POLLIN) {
|
||||
forced = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ah = ah->next;
|
||||
}
|
||||
|
||||
return forced;
|
||||
}
|
||||
|
@ -809,6 +814,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
|
|||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
lws_sockfd_type our_fd = 0, tmp_fd;
|
||||
struct allocated_headers *ah;
|
||||
struct lws_tokens eff_buf;
|
||||
unsigned int pending = 0;
|
||||
struct lws *wsi, *wsi1;
|
||||
|
@ -888,62 +894,66 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
|
|||
* timeout status
|
||||
*/
|
||||
|
||||
for (n = 0; n < context->max_http_header_pool; n++)
|
||||
if (pt->ah_pool[n].in_use && pt->ah_pool[n].wsi &&
|
||||
pt->ah_pool[n].assigned &&
|
||||
now - pt->ah_pool[n].assigned > 60) {
|
||||
int len;
|
||||
char buf[256];
|
||||
const unsigned char *c;
|
||||
ah = pt->ah_list;
|
||||
while (ah) {
|
||||
int len;
|
||||
char buf[256];
|
||||
const unsigned char *c;
|
||||
|
||||
/*
|
||||
* a single ah session somehow got held for
|
||||
* an unreasonable amount of time.
|
||||
*
|
||||
* Dump info on the connection...
|
||||
*/
|
||||
|
||||
wsi = pt->ah_pool[n].wsi;
|
||||
buf[0] = '\0';
|
||||
lws_get_peer_simple(wsi, buf, sizeof(buf));
|
||||
lwsl_notice("ah excessive hold: wsi %p\n"
|
||||
" peer address: %s\n"
|
||||
" ah rxpos %u, rxlen %u, pos %u\n",
|
||||
wsi, buf, pt->ah_pool[n].rxpos,
|
||||
pt->ah_pool[n].rxlen,
|
||||
pt->ah_pool[n].pos);
|
||||
buf[0] = '\0';
|
||||
m = 0;
|
||||
do {
|
||||
c = lws_token_to_string(m);
|
||||
if (!c)
|
||||
break;
|
||||
|
||||
len = lws_hdr_total_length(wsi, m);
|
||||
if (!len || len > sizeof(buf) - 1) {
|
||||
m++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lws_hdr_copy(wsi, buf,
|
||||
sizeof buf, m) > 0) {
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
|
||||
lwsl_notice(" %s = %s\n",
|
||||
(const char *)c, buf);
|
||||
}
|
||||
m++;
|
||||
} while (1);
|
||||
|
||||
/* ... and then drop the connection */
|
||||
|
||||
if (wsi->desc.sockfd == our_fd)
|
||||
/* it was the guy we came to service! */
|
||||
timed_out = 1;
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
if (!ah->in_use || !ah->wsi || !ah->assigned ||
|
||||
now - ah->assigned < 60) {
|
||||
ah = ah->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* a single ah session somehow got held for
|
||||
* an unreasonable amount of time.
|
||||
*
|
||||
* Dump info on the connection...
|
||||
*/
|
||||
wsi = ah->wsi;
|
||||
buf[0] = '\0';
|
||||
lws_get_peer_simple(wsi, buf, sizeof(buf));
|
||||
lwsl_notice("ah excessive hold: wsi %p\n"
|
||||
" peer address: %s\n"
|
||||
" ah rxpos %u, rxlen %u, pos %u\n",
|
||||
wsi, buf, ah->rxpos, ah->rxlen,
|
||||
ah->pos);
|
||||
buf[0] = '\0';
|
||||
m = 0;
|
||||
do {
|
||||
c = lws_token_to_string(m);
|
||||
if (!c)
|
||||
break;
|
||||
|
||||
len = lws_hdr_total_length(wsi, m);
|
||||
if (!len || len > sizeof(buf) - 1) {
|
||||
m++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lws_hdr_copy(wsi, buf,
|
||||
sizeof buf, m) > 0) {
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
|
||||
lwsl_notice(" %s = %s\n",
|
||||
(const char *)c, buf);
|
||||
}
|
||||
m++;
|
||||
} while (1);
|
||||
|
||||
/* ... and then drop the connection */
|
||||
|
||||
if (wsi->desc.sockfd == our_fd)
|
||||
/* it was the guy we came to service! */
|
||||
timed_out = 1;
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||
|
||||
ah = ah->next;
|
||||
}
|
||||
|
||||
#ifdef LWS_WITH_CGI
|
||||
/*
|
||||
* Phase 3: handle cgi timeouts
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#ifndef LWS_NO_SERVER
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
|
||||
struct alpn_ctx {
|
||||
unsigned char *data;
|
||||
|
@ -89,7 +89,7 @@ alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
|
|||
LWS_VISIBLE void
|
||||
lws_context_init_http2_ssl(struct lws_vhost *vhost)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
static struct alpn_ctx protos = { (unsigned char *)"\x02h2"
|
||||
"\x08http/1.1", 6 + 9 };
|
||||
|
||||
|
@ -107,7 +107,7 @@ lws_context_init_http2_ssl(struct lws_vhost *vhost)
|
|||
|
||||
void lws_http2_configure_if_upgraded(struct lws *wsi)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
#if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
struct allocated_headers *ah;
|
||||
const char *method = "alpn";
|
||||
const unsigned char *name;
|
||||
|
|
|
@ -137,7 +137,7 @@ lws_context_ssl_init_ecdh_curve(struct lws_context_creation_info *info,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(SSL_TLSEXT_ERR_NOACK) && !defined(OPENSSL_NO_TLSEXT)
|
||||
#if !defined(LWS_WITH_MBEDTLS) && defined(SSL_TLSEXT_ERR_NOACK) && !defined(OPENSSL_NO_TLSEXT)
|
||||
static int
|
||||
lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg)
|
||||
{
|
||||
|
|
|
@ -119,7 +119,7 @@ context_creation(void)
|
|||
memset(&info, 0, sizeof(info));
|
||||
|
||||
info.external_baggage_free_on_destroy = config_strings;
|
||||
info.max_http_header_pool = 16;
|
||||
info.max_http_header_pool = 256;
|
||||
info.options = opts | LWS_SERVER_OPTION_VALIDATE_UTF8 |
|
||||
LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
|
||||
LWS_SERVER_OPTION_LIBUV;
|
||||
|
|
Loading…
Add table
Reference in a new issue