mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
TCP_FASTOPEN
This commit is contained in:
parent
f9ae34c320
commit
ad3aa5339e
8 changed files with 96 additions and 13 deletions
32
READMEs/README.tcp_fastopen.md
Normal file
32
READMEs/README.tcp_fastopen.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
# `TCP_FASTOPEN` support in lws
|
||||
|
||||
Lws supports enabling TCP_FASTOPEN oper-vhost for listen sockets.
|
||||
|
||||
## Enabling per vhost serving
|
||||
|
||||
Set the `info.fo_listen_queue` to nonzero at vhost creation. Different
|
||||
platforms interpret this number differently, zero always disables it
|
||||
but on Linux, the number is interpreted as a SYN queue length.
|
||||
|
||||
On FreeBSD, OSX and Windows, the number is basically a bool, with the
|
||||
extra restriction OSX and Windows only allows 0 or 1.
|
||||
|
||||
## Enabling Linux for serving with TCP_FASTOPEN
|
||||
|
||||
To configure the kernel for listening socket TCP_FASTOPEN, you need
|
||||
|
||||
```
|
||||
# sysctl -w net.ipv4.tcp_fastopen=3
|
||||
```
|
||||
|
||||
## Enabling BSD for serving with TCP_FASTOPEN
|
||||
|
||||
At least on FreeBSD, you need to set the net.inet.tcp.fastopen.enabled
|
||||
sysctl to 1
|
||||
|
||||
## Enabling Windows for serving with TCP_FASTOPEN
|
||||
|
||||
```
|
||||
> netsh int tcp set global fastopenfallback=disabled
|
||||
> netsh int tcp show global
|
||||
```
|
|
@ -854,16 +854,22 @@ struct lws_context_creation_info {
|
|||
|
||||
#if defined(LWS_WITH_SYS_METRICS)
|
||||
const struct lws_metric_policy *metrics_policies;
|
||||
/**< non-SS policy metrics policies */
|
||||
/**< CONTEXT: non-SS policy metrics policies */
|
||||
const char *metrics_prefix;
|
||||
/**< prefix for this context's metrics, used to distinguish metrics
|
||||
* pooled from different processes / applications, so, eg what would
|
||||
* be "cpu.svc" if this is NULL becomes "myapp.cpu.svc" is this is
|
||||
/**< CONTEXT: prefix for this context's metrics, used to distinguish
|
||||
* metrics pooled from different processes / applications, so, eg what
|
||||
* would be "cpu.svc" if this is NULL becomes "myapp.cpu.svc" is this is
|
||||
* set to "myapp". Policies are applied using the name with the prefix,
|
||||
* if present.
|
||||
*/
|
||||
#endif
|
||||
|
||||
int fo_listen_queue;
|
||||
/**< VHOST: 0 = no TCP_FASTOPEN, nonzero = enable TCP_FASTOPEN if the
|
||||
* platform supports it, with the given queue length for the listen
|
||||
* socket.
|
||||
*/
|
||||
|
||||
/* Add new things just above here ---^
|
||||
* This is part of the ABI, don't needlessly break compatibility
|
||||
*
|
||||
|
|
|
@ -535,6 +535,7 @@ struct lws_vhost {
|
|||
int keepalive_timeout;
|
||||
int timeout_secs_ah_idle;
|
||||
int connect_timeout_secs;
|
||||
int fo_listen_queue;
|
||||
|
||||
int count_bound_wsi;
|
||||
|
||||
|
|
|
@ -659,15 +659,16 @@ lws_create_vhost(struct lws_context *context,
|
|||
vh->count_protocols++)
|
||||
;
|
||||
|
||||
vh->options = info->options;
|
||||
vh->pvo = info->pvo;
|
||||
vh->headers = info->headers;
|
||||
vh->user = info->user;
|
||||
vh->finalize = info->finalize;
|
||||
vh->finalize_arg = info->finalize_arg;
|
||||
vh->listen_accept_role = info->listen_accept_role;
|
||||
vh->listen_accept_protocol = info->listen_accept_protocol;
|
||||
vh->unix_socket_perms = info->unix_socket_perms;
|
||||
vh->options = info->options;
|
||||
vh->pvo = info->pvo;
|
||||
vh->headers = info->headers;
|
||||
vh->user = info->user;
|
||||
vh->finalize = info->finalize;
|
||||
vh->finalize_arg = info->finalize_arg;
|
||||
vh->listen_accept_role = info->listen_accept_role;
|
||||
vh->listen_accept_protocol = info->listen_accept_protocol;
|
||||
vh->unix_socket_perms = info->unix_socket_perms;
|
||||
vh->fo_listen_queue = info->fo_listen_queue;
|
||||
|
||||
LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar)
|
||||
if (lws_rops_fidx(ar, LWS_ROPS_init_vhost) &&
|
||||
|
|
|
@ -220,6 +220,16 @@ lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags)
|
|||
int en;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if defined(TCP_FASTOPEN_CONNECT)
|
||||
optval = 1;
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, (void *)&optval,
|
||||
sizeof(optval)))
|
||||
lwsl_warn("%s: FASTOPEN_CONNECT failed\n", __func__);
|
||||
optval = (int)pri;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__APPLE__) && \
|
||||
!defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) && \
|
||||
!defined(__NetBSD__) && \
|
||||
|
|
|
@ -119,6 +119,7 @@ static const char * const paths_vhosts[] = {
|
|||
"vhosts[].ignore-missing-cert",
|
||||
"vhosts[].error-document-404",
|
||||
"vhosts[].alpn",
|
||||
"vhosts[].fo-listen-queue",
|
||||
"vhosts[].ssl-client-option-set",
|
||||
"vhosts[].ssl-client-option-clear",
|
||||
"vhosts[].tls13-ciphers",
|
||||
|
@ -187,6 +188,7 @@ enum lejp_vhost_paths {
|
|||
LEJPVP_IGNORE_MISSING_CERT,
|
||||
LEJPVP_ERROR_DOCUMENT_404,
|
||||
LEJPVP_ALPN,
|
||||
LWJPVP_FO_LISTEN_QUEUE,
|
||||
LEJPVP_SSL_CLIENT_OPTION_SET,
|
||||
LEJPVP_SSL_CLIENT_OPTION_CLEAR,
|
||||
LEJPVP_TLS13_CIPHERS,
|
||||
|
@ -693,6 +695,9 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
|
|||
case LEJPVP_CGI_TIMEOUT:
|
||||
a->m.cgi_timeout = atoi(ctx->buf);
|
||||
return 0;
|
||||
case LWJPVP_FO_LISTEN_QUEUE:
|
||||
a->info->fo_listen_queue = atoi(ctx->buf);
|
||||
return 0;
|
||||
case LEJPVP_KEEPALIVE_TIMEOUT:
|
||||
a->info->keepalive_timeout = atoi(ctx->buf);
|
||||
return 0;
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
|
||||
#include "private-lib-core.h"
|
||||
|
||||
#if !defined(SOL_TCP) && defined(IPPROTO_TCP)
|
||||
#define SOL_TCP IPPROTO_TCP
|
||||
#endif
|
||||
|
||||
const char * const method_names[] = {
|
||||
"GET", "POST",
|
||||
#if defined(LWS_WITH_HTTP_UNCOMMON_HEADERS)
|
||||
|
@ -345,6 +349,29 @@ done_list:
|
|||
vhost->lserv_wsi = wsi;
|
||||
lws_pt_unlock(pt);
|
||||
|
||||
#if defined(WIN32) && defined(TCP_FASTOPEN)
|
||||
if (vhost->fo_listen_queue) {
|
||||
int optval = 1;
|
||||
if (setsockopt(wsi->desc.sockfd, IPPROTO_TCP,
|
||||
TCP_FASTOPEN,
|
||||
(const char*)&optval, sizeof(optval)) < 0) {
|
||||
int error = LWS_ERRNO;
|
||||
lwsl_warn("%s: TCP_NODELAY failed with error %d\n",
|
||||
__func__, error);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if defined(TCP_FASTOPEN)
|
||||
if (vhost->fo_listen_queue) {
|
||||
int qlen = vhost->fo_listen_queue;
|
||||
|
||||
if (setsockopt(wsi->desc.sockfd, SOL_TCP, TCP_FASTOPEN,
|
||||
&qlen, sizeof(qlen)))
|
||||
lwsl_warn("%s: TCP_FASTOPEN failed\n", __func__);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
n = listen(wsi->desc.sockfd, LWS_SOMAXCONN);
|
||||
if (n < 0) {
|
||||
lwsl_err("listen failed with error %d\n", LWS_ERRNO);
|
||||
|
|
|
@ -126,6 +126,7 @@ int main(int argc, const char **argv)
|
|||
LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
|
||||
info.ssl_cert_filepath = "localhost-100y.cert";
|
||||
info.ssl_private_key_filepath = "localhost-100y.key";
|
||||
info.fo_listen_queue = 32;
|
||||
|
||||
#if defined(LWS_WITH_PLUGINS)
|
||||
info.plugin_dirs = plugin_dirs;
|
||||
|
|
Loading…
Add table
Reference in a new issue