Commit Graph

230 Commits

Author SHA1 Message Date
Aperence
f33492028e
HTTP: added MPTCP support.
Multipath TCP (MPTCP), standardized in RFC8684 [1], is a TCP extension
that enables a TCP connection to use different paths.

Multipath TCP has been used for several use cases. On smartphones, MPTCP
enables seamless handovers between cellular and Wi-Fi networks while
preserving Established connections. This use-case is what pushed Apple
to use MPTCP since 2013 in multiple applications [2]. On dual-stack
hosts, Multipath TCP enables the TCP connection to automatically use the
best performing path, either IPv4 or IPv6. If one path fails, MPTCP
automatically uses the other path.

The benefit from MPTCP, both the client and the server have to support
it. Multipath TCP is a backward-compatible TCP extension that is enabled
by default on recent Linux distributions (Debian, Ubuntu, Redhat, ...).
Multipath TCP is included in the Linux kernel since version 5.6 [3].
To use it on Linux, an application must explicitly enable it when
creating the socket. No need to change anything else in the application.

Even if MPTCP is supported by different OS, only Linux supports the
`IPPROTO_MPTCP` protocol, which is why this feature is currently
limited to Linux only.

This patch adds a new parameter 'multipath' to the 'listen' directive
in the HTTP module. This new parameter is only compatible with TCP if
IPPROTO_MPTCP is defined, not with QUIC so far.

Co-authored-by: Maxime Dourov <mux99@live.be>

Link: https://www.rfc-editor.org/rfc/rfc8684.html [1]
Link: https://www.tessares.net/apples-mptcp-story-so-far/ [2]
Link: https://www.mptcp.dev [3]
2024-09-06 20:42:51 +02:00
Roman Arutyunyan
0a3c796145 Common tree insert function for QUIC and UDP connections.
Previously, ngx_udp_rbtree_insert_value() was used for plain UDP and
ngx_quic_rbtree_insert_value() was used for QUIC.  Because of this it was
impossible to initialize connection tree in ngx_create_listening() since
this function is not aware what kind of listening it creates.

Now ngx_udp_rbtree_insert_value() is used for both QUIC and UDP.  To make
is possible, a generic key field is added to ngx_udp_connection_t.  It keeps
client address for UDP and connection ID for QUIC.
2023-05-14 12:30:11 +04:00
Roman Arutyunyan
2ce3eeeeb7 HTTP/3: removed "http3" parameter of "listen" directive.
The parameter has been deprecated since c851a2ed5ce8.
2023-05-11 13:22:10 +04:00
Sergey Kandaurov
e8fbc96747 Merged with the default branch. 2023-03-29 11:14:25 +04:00
Maxim Dounin
dad65f3e44 Added warning about redefinition of listen socket protocol options.
The "listen" directive in the http module can be used multiple times
in different server blocks.  Originally, it was supposed to be specified
once with various socket options, and without any parameters in virtual
server blocks.  For example:

    server { listen 80 backlog=1024; server_name foo; ... }
    server { listen 80; server_name bar; ... }
    server { listen 80; server_name bazz; ... }

The address part of the syntax ("address[:port]" / "port" / "unix:path")
uniquely identifies the listening socket, and therefore is enough for
name-based virtual servers (to let nginx know that the virtual server
accepts requests on the listening socket in question).

To ensure that listening options do not conflict between virtual servers,
they were allowed only once.  For example, the following configuration
will be rejected ("duplicate listen options for 0.0.0.0:80 in ..."):

    server { listen 80 backlog=1024; server_name foo; ... }
    server { listen 80 backlog=512; server_name bar; ... }

At some point it was, however, noticed, that it is sometimes convenient
to repeat some options for clarity.  In nginx 0.8.51 the "ssl" parameter
was allowed to be specified multiple times, e.g.:

    server { listen 443 ssl backlog=1024; server_name foo; ... }
    server { listen 443 ssl; server_name bar; ... }
    server { listen 443 ssl; server_name bazz; ... }

This approach makes configuration more readable, since SSL sockets are
immediately visible in the configuration.  If this is not needed, just the
address can still be used.

Later, additional protocol-specific options similar to "ssl" were
introduced, notably "http2" and "proxy_protocol".  With these options,
one can write:

    server { listen 443 ssl backlog=1024; server_name foo; ... }
    server { listen 443 http2; server_name bar; ... }
    server { listen 443 proxy_protocol; server_name bazz; ... }

The resulting socket will use ssl, http2, and proxy_protocol, but this
is not really obvious from the configuration.

To emphasize such misleading configurations are discouraged, nginx now
warns as long as the "listen" directive is used with options different
from the options previously used if this is potentially confusing.

In particular, the following configurations are allowed:

    server { listen 8401 ssl backlog=1024; server_name foo; }
    server { listen 8401 ssl; server_name bar; }
    server { listen 8401 ssl; server_name bazz; }

    server { listen 8402 ssl http2 backlog=1024; server_name foo; }
    server { listen 8402 ssl; server_name bar; }
    server { listen 8402 ssl; server_name bazz; }

    server { listen 8403 ssl; server_name bar; }
    server { listen 8403 ssl; server_name bazz; }
    server { listen 8403 ssl http2; server_name foo; }

    server { listen 8404 ssl http2 backlog=1024; server_name foo; }
    server { listen 8404 http2; server_name bar; }
    server { listen 8404 http2; server_name bazz; }

    server { listen 8405 ssl http2 backlog=1024; server_name foo; }
    server { listen 8405 ssl http2; server_name bar; }
    server { listen 8405 ssl http2; server_name bazz; }

    server { listen 8406 ssl; server_name foo; }
    server { listen 8406; server_name bar; }
    server { listen 8406; server_name bazz; }

And the following configurations will generate warnings:

    server { listen 8501 ssl http2 backlog=1024; server_name foo; }
    server { listen 8501 http2; server_name bar; }
    server { listen 8501 ssl; server_name bazz; }

    server { listen 8502 backlog=1024; server_name foo; }
    server { listen 8502 ssl; server_name bar; }

    server { listen 8503 ssl; server_name foo; }
    server { listen 8503 http2; server_name bar; }

    server { listen 8504 ssl; server_name foo; }
    server { listen 8504 http2; server_name bar; }
    server { listen 8504 proxy_protocol; server_name bazz; }

    server { listen 8505 ssl http2 proxy_protocol; server_name foo; }
    server { listen 8505 ssl http2; server_name bar; }
    server { listen 8505 ssl; server_name bazz; }

    server { listen 8506 ssl http2; server_name foo; }
    server { listen 8506 ssl; server_name bar; }
    server { listen 8506; server_name bazz; }

    server { listen 8507 ssl; server_name bar; }
    server { listen 8507; server_name bazz; }
    server { listen 8507 ssl http2; server_name foo; }

    server { listen 8508 ssl; server_name bar; }
    server { listen 8508; server_name bazz; }
    server { listen 8508 ssl backlog=1024; server_name foo; }

    server { listen 8509; server_name bazz; }
    server { listen 8509 ssl; server_name bar; }
    server { listen 8509 ssl backlog=1024; server_name foo; }

The basic idea is that at most two sets of protocol options are allowed:
the main one (with socket options, if any), and a shorter one, with options
being a subset of the main options, repeated for clarity.  As long as the
shorter set of protocol options is used, all listen directives except the
main one should use it.
2023-01-28 01:29:45 +03:00
Roman Arutyunyan
815ef96124 HTTP/3: "quic" parameter of "listen" directive.
Now "listen" directve has a new "quic" parameter which enables QUIC protocol
for the address.  Further, to enable HTTP/3, a new directive "http3" is
introduced.  The hq-interop protocol is enabled by "http3_hq" as before.
Now application protocol is chosen by ALPN.

Previously used "http3" parameter of "listen" is deprecated.
2023-02-27 14:00:56 +04:00
Maxim Dounin
f20c6e0eb5 Fixed handling of very long locations (ticket #2435).
Previously, location prefix length in ngx_http_location_tree_node_t was
stored as "u_char", and therefore location prefixes longer than 255 bytes
were handled incorrectly.

Fix is to use "u_short" instead.  With "u_short", prefixes up to 65535 bytes
can be safely used, and this isn't reachable due to NGX_CONF_BUFFER, which
is 4096 bytes.
2023-01-26 03:34:44 +03:00
Roman Arutyunyan
9d81ef744c QUIC: separate UDP framework for QUIC.
Previously, QUIC used the existing UDP framework, which was created for UDP in
Stream.  However the way QUIC connections are created and looked up is different
from the way UDP connections in Stream are created and looked up.  Now these
two implementations are decoupled.
2022-04-20 16:01:17 +04:00
Sergey Kandaurov
a7a3a8cc17 HTTP/3: removed useless warning regarding OpenSSL library.
After 0e6528551f26, it became impossible to run into this path.
2022-01-13 15:57:15 +03:00
Roman Arutyunyan
d84c1f7885 HTTP/3: http3_hq directive and NGX_HTTP_V3_HQ macro.
Listen quic parameter is no longer supported.
2021-12-04 10:52:55 +03:00
Roman Arutyunyan
731915a0c5 HTTP/3: merged ngx_http_quic_module into ngx_http_v3_module. 2021-12-06 13:02:36 +03:00
Sergey Kandaurov
bbd05ae252 Merged with the default branch. 2021-11-03 11:22:07 +03:00
Ruslan Ermilov
bd89c448b7 Removed NGX_OPENSSL_QUIC macro, NGX_QUIC is enough. 2021-09-14 12:09:13 +03:00
Vladimir Homutov
1db517fb71 HTTP/2: removed support for NPN.
NPN was replaced with ALPN, published as RFC 7301 in July 2014.
It used to negotiate SPDY (and, in transition, HTTP/2).

NPN supported appeared in OpenSSL 1.0.1. It does not work with TLSv1.3 [1].
ALPN is supported since OpenSSL 1.0.2.

The NPN support was dropped in Firefox 53 [2] and Chrome 51 [3].

[1] https://github.com/openssl/openssl/issues/3665.
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=1248198
[3] https://www.chromestatus.com/feature/5767920709795840
2021-10-15 10:02:15 +03:00
Sergey Kandaurov
b2b8637f98 Merged with the default branch. 2021-05-28 13:33:08 +03:00
Ruslan Ermilov
41a241b3ef Location header escaping in redirects (ticket #882).
The header is escaped in redirects based on request URI or
location name (auto redirect).
2021-05-24 21:55:20 +03:00
Sergey Kandaurov
8ca2f73073 Merged with the default branch. 2021-02-17 14:48:35 +03:00
Maxim Dounin
2ec8fac2d6 Core: removed post_accept_timeout.
Keeping post_accept_timeout in ngx_listening_t is no longer needed since
we've switched to 1 second timeout for deferred accept in 5541:fdb67cfc957d.

Further, using it in HTTP code can result in client_header_timeout being
used from an incorrect server block, notably if address-specific virtual
servers are used along with a wildcard listening socket, or if we've switched
to a different server block based on SNI in SSL handshake.
2021-01-19 20:32:00 +03:00
Roman Arutyunyan
b813b9ec35 QUIC: added "quic" listen parameter.
The parameter allows processing HTTP/0.9-2 over QUIC.

Also, introduced ngx_http_quic_module and moved QUIC settings there
2020-07-21 23:09:22 +03:00
Sergey Kandaurov
2346ee29e1 Merged with the default branch. 2020-07-13 15:34:22 +03:00
Sergey Kandaurov
9d46500914 Do not close QUIC sockets in ngx_close_listening_sockets().
This breaks graceful shutdown of QUIC connections in terms of quic-transport.
2020-06-23 11:57:00 +03:00
Eran Kornblau
1bbc37d35c Fixed potential leak of temp pool.
In case ngx_hash_add_key() fails, need to goto failed instead of returning,
so that temp_pool will be destoryed.
2020-06-15 03:58:31 -04:00
Vladimir Homutov
101113a98f Added propagation of the "wildcard" flag to c->listening.
The flags was originally added by 8f038068f4bc, and is propagated correctly
in the stream module.  With QUIC introduction, http module now uses datagram
sockets as well, thus the fix.
2020-05-29 13:29:24 +03:00
Sergey Kandaurov
26ac1c73f0 Initial QUIC support in http. 2020-02-28 13:09:51 +03:00
Sergey Kandaurov
e92cb24f40 HTTP UDP layer, QUIC support autotest. 2020-02-28 13:09:51 +03:00
Roman Arutyunyan
4e17b93eb6 Multiple addresses in "listen".
Previously only one address was used by the listen directive handler even if
host name resolved to multiple addresses.  Now a separate listening socket is
created for each address.
2019-03-15 15:45:56 +03:00
Maxim Dounin
751bdd3bb2 Events: moved sockets cloning to ngx_event_init_conf().
Previously, listenings sockets were not cloned if the worker_processes
directive was specified after "listen ... reuseport".

This also simplifies upcoming configuration check on the number
of worker connections, as it needs to know the number of listening
sockets before cloning.
2018-07-12 19:50:02 +03:00
Roman Arutyunyan
129b06dc5d Precontent phase.
The phase is added instead of the try_files phase.  Unlike the old phase, the
new one supports registering multiple handlers.  The try_files implementation is
moved to a separate ngx_http_try_files_module, which now registers a precontent
phase handler.
2017-07-20 15:51:11 +03:00
Alex Zhang
2c8f93df87 Style.
Signed-off-by: Alex Zhang <zchao1995@gmail.com>
2017-07-19 21:39:40 +08:00
Ruslan Ermilov
7d34042e4a The size of cmcf->phase_engine.handlers explained. 2016-12-13 22:00:49 +03:00
Maxim Dounin
0a961a0917 Modules compatibility: removed unneeded IPV6_V6ONLY checks.
The IPV6_V6ONLY macro is now checked only while parsing appropriate flag
and when using the macro.

The ipv6only field in listen structures is always initialized to 1,
even if not supported on a given platform.  This is expected to prevent
a module compiled without IPV6_V6ONLY from accidentally creating dual
sockets if loaded into main binary with proper IPV6_V6ONLY support.
2016-10-03 15:58:25 +03:00
Roman Arutyunyan
5b201ac31f Introduced ngx_inet_get_port() and ngx_inet_set_port() functions. 2016-06-20 11:50:39 +03:00
Maxim Dounin
5b267a55bc Renamed "u" to "sockaddr" in listen options types. 2016-05-23 16:37:28 +03:00
Ruslan Ermilov
48a16463fa Use ngx_cmp_sockaddr() where appropriate. 2016-05-20 19:10:42 +03:00
Maxim Dounin
0f67d6355c Dynamic modules: changed ngx_modules to cycle->modules. 2016-02-04 18:30:21 +03:00
Maxim Dounin
7988334570 Dynamic modules: moved module-related stuff to separate files. 2016-02-04 18:30:21 +03:00
Maxim Dounin
9973e36944 Fixed PROXY protocol on IPv6 sockets (ticket #858). 2015-12-17 16:39:02 +03:00
Valentin Bartenev
ee37ff613f The HTTP/2 implementation (RFC 7240, 7241).
The SPDY support is removed, as it's incompatible with the new module.
2015-09-11 20:13:06 +03:00
Vladimir Homutov
b7a8f2a08f Disabled duplicate http, mail, and stream blocks.
Such configurations have very limited use, introduce various problems and
are not officially supported.
2015-06-16 23:28:38 +03:00
Maxim Dounin
f7f1607bf2 The "reuseport" option of the "listen" directive.
When configured, an individual listen socket on a given address is
created for each worker process.  This allows to reduce in-kernel lock
contention on configurations with high accept rates, resulting in better
performance.  As of now it works on Linux and DragonFly BSD.

Note that on Linux incoming connection requests are currently tied up
to a specific listen socket, and if some sockets are closed, connection
requests will be reset, see https://lwn.net/Articles/542629/.  With
nginx, this may happen if the number of worker processes is reduced.
There is no such problem on DragonFly BSD.

Based on previous work by Sepherosa Ziehau and Yingqi Lu.
2015-05-20 15:51:56 +03:00
Maxim Dounin
d5c34785bc Simplified ngx_http_init_listening().
There is no need to set "i" to 0, as it's expected to be 0 assuming
the bindings are properly sorted, and we already rely on this when
explicitly set hport->naddrs to 1.  Remaining conditional code is
replaced with identical "hport->naddrs = i + 1".

Identical modifications are done in the mail and stream modules,
in the ngx_mail_optimize_servers() and ngx_stream_optimize_servers()
functions, respectively.

No functional changes.
2015-05-20 15:51:28 +03:00
Roman Arutyunyan
d61f21c5e8 Merge proxy_protocol setting of listen directives.
It's now enough to specify proxy_protocol option in one listen directive to
enable it in all servers listening on the same address/port.  Previously,
the setting from the first directive was always used.
2015-04-24 10:54:06 +03:00
Maxim Dounin
d02d2cff9b Request body: filters support. 2015-03-23 21:09:19 +03:00
Gu Feng
bba2ce8aae Avoided to add duplicate hash key in ngx_http_types_slot(). 2014-09-17 22:52:02 +08:00
Maxim Dounin
25250a20d2 Fixed wrong sizeof() in ngx_http_init_locations().
There is no real difference on all known platforms, but it's still wrong.

Found by Coverity (CID 400876).
2014-06-26 03:34:13 +04:00
Roman Arutyunyan
0b5f329784 Added server-side support for PROXY protocol v1 (ticket #355).
Client address specified in the PROXY protocol header is now
saved in the $proxy_protocol_addr variable and can be used in
the realip module.

This is currently not implemented for mail.
2014-03-17 17:41:24 +04:00
Piotr Sikora
4ae889c9f2 SSL: support ALPN (IETF's successor to NPN).
Signed-off-by: Piotr Sikora <piotr@cloudflare.com>
2014-01-28 15:33:49 -08:00
Mathew Rodley
84f5c2136e Added support for TCP_FASTOPEN supported in Linux >= 3.7.1.
---
 auto/unix                       | 12 ++++++++++++
 src/core/ngx_connection.c       | 32 ++++++++++++++++++++++++++++++++
 src/core/ngx_connection.h       |  4 ++++
 src/http/ngx_http.c             |  4 ++++
 src/http/ngx_http_core_module.c | 21 +++++++++++++++++++++
 src/http/ngx_http_core_module.h |  3 +++
 6 files changed, 76 insertions(+)
2013-12-03 22:07:03 +04:00
Maxim Dounin
d2ef70e97a Caseless location tree construction (ticket #90).
Location tree was always constructed using case-sensitive comparison, even
on case-insensitive systems.  This resulted in incorrect operation if
uppercase letters were used in location directives.  Notably, the
following config:

    location /a { ... }
    location /B { ... }

failed to properly map requests to "/B" into "location /B".
2013-09-23 19:37:06 +04:00
Ruslan Ermilov
56fce56f4f Use NGX_DEFAULT_POOL_SIZE macro where appropriate. 2013-03-21 16:03:24 +00:00