Commit Graph

6957 Commits

Author SHA1 Message Date
Sergey Kandaurov
a0cc9398ed Preserve original DCID and unbreak parsing 0-RTT packets.
As per QUIC transport, the first flight of 0-RTT packets obviously uses same
Destination and Source Connection ID values as the client's first Initial.

The fix is to match 0-RTT against original DCID after it has been switched.
2020-05-12 18:18:58 +03:00
Sergey Kandaurov
7ab07b3409 Removed redundant long packet type checks. 2020-05-09 17:41:07 +03:00
Sergey Kandaurov
13fb3fbd67 Removed redundant SSL_do_handshake call before any handshake data. 2020-05-09 17:39:47 +03:00
Vladimir Homutov
7017a64183 Cleaned up reordering code.
The ordered frame handler is always called for the existing stream, as it is
allocated from this stream.  Instead of searching stream by id, pointer to the
stream node is passed.
2020-05-08 13:08:04 +03:00
Vladimir Homutov
1816f3af58 Cleaned up firefox workaround.
The idea is to skip any zeroes that follow valid QUIC packet.  Currently such
behavior can be only observed with Firefox which sends zero-padded initial
packets.
2020-05-07 12:34:04 +03:00
Roman Arutyunyan
3f2ac979eb OCSP stapling: moved response verification to a separate function. 2020-05-06 21:44:14 +03:00
Jinhua Tan
b47c1f35e2 Upstream: jump out of loop after matching the status code. 2020-05-13 22:02:47 +08:00
Sergey Kandaurov
41ecd45a5b Variables: fixed buffer over-read when evaluating "$arg_". 2020-05-08 19:19:16 +03:00
Sergey Kandaurov
9ed0d4c9ae Restored ngx_quic_encrypt return type.
It was inadvertently changed while working on removing memory allocations.
2020-05-06 14:34:44 +03:00
Vladimir Homutov
5e5c703656 Store clearflags in pkt->flags after decryption.
It doesn't make sense to store protected flags.
2020-04-30 12:22:35 +03:00
Sergey Kandaurov
1a6fc01fb8 Configure: fixed static compilation with OpenSSL 1.1.1 / BoringSSL.
See 7246:04ebf29eaf5b for details.
2020-05-01 13:02:30 +03:00
Sergey Kandaurov
cf5168c9e0 Mention quic branch in README. 2020-04-30 15:59:14 +03:00
Sergey Kandaurov
b7b3aca704 Configure: unbreak with old OpenSSL, --with-http_v3_module added. 2020-04-30 15:47:43 +03:00
Vladimir Homutov
be47823248 Removed outdated/incorrect comments and fixed style.
- we need transport parameters early to get packet size limits at least.
2020-04-29 14:45:55 +03:00
Vladimir Homutov
ed461dbff7 Reworked macros for parsing/assembling packet types.
Previously, macros checking a packet type with the long header also checked
whether this is a long header.  Now it requires a separate preceding check.
2020-04-30 12:38:38 +03:00
Sergey Kandaurov
4c2ccf217a Renamed retransmit event object in preparation for retry support. 2020-04-29 14:59:21 +03:00
Sergey Kandaurov
9aeb2c0ece Server CID change. 2020-04-28 18:24:01 +03:00
Sergey Kandaurov
467c8a13c9 Factored out sending ACK from payload handler.
Now there's no need to annotate every frame in ACK-eliciting packet.
Sending ACK was moved to the first place, so that queueing ACK frame
no longer postponed up to the next packet after pushing STREAM frames.
2020-04-28 18:23:56 +03:00
Vladimir Homutov
6582758e18 Added README. 2020-04-28 18:16:13 +03:00
Roman Arutyunyan
7509f967f7 Respect MAX_DATA and MAX_STREAM_DATA from QUIC client. 2020-04-28 16:37:32 +03:00
Roman Arutyunyan
75acaec13a QUIC basic congestion control. 2020-04-28 16:42:43 +03:00
Roman Arutyunyan
60c8a601d0 Fixed packet retransmission.
Previously frames in ctx->sent queue could be lost.
2020-04-24 17:20:37 +03:00
Roman Arutyunyan
9c37591016 Assign connection number to every QUIC stream log. 2020-04-23 18:05:05 +03:00
Vladimir Homutov
2e4cd7a2e5 Error messages cleanup.
+ added "quic" prefix to all error messages
 + rephrased some messages
 + removed excessive error logging from frame parser
 + added ngx_quic_check_peer() function to check proper source/destination
   match and do it one place
2020-04-24 14:38:49 +03:00
Vladimir Homutov
62943dfa08 Cleaned up hexdumps in debug output.
- the ngx_quic_hexdump0() macro is renamed to ngx_quic_hexdump();
   the original ngx_quic_hexdump() macro with variable argument is
   removed, extra information is logged normally, with ngx_log_debug()

 - all labels in hex dumps are prefixed with "quic"

 - the hexdump format is simplified, length is moved forward to avoid
   situations when the dump is truncated, and length is not shown

 - ngx_quic_flush_flight() function contents is debug-only, placed under
   NGX_DEBUG macro to avoid "unused variable" warnings from compiler

 - frame names in labels are capitalized, similar to other places
2020-04-24 11:33:00 +03:00
Vladimir Homutov
a9ef6ed17d Debug cleanup.
+ all dumps are moved under one of the following macros (undefined by default):
    NGX_QUIC_DEBUG_PACKETS
    NGX_QUIC_DEBUG_FRAMES
    NGX_QUIC_DEBUG_FRAMES_ALLOC
    NGX_QUIC_DEBUG_CRYPTO

 + all QUIC debug messages got "quic " prefix

 + all input frames are reported as "quic frame in FOO_FRAME bar:1 baz:2"

 + all outgoing frames re reported as "quic frame out foo bar baz"

 + all stream operations are prefixed with id, like: "quic stream id 0x33 recv"

 + all transport parameters are prefixed with "quic tp"
   (hex dump is moved to caller, to avoid using ngx_cycle->log)

 + packet flags and some other debug messages are updated to
   include packet type
2020-04-24 10:11:47 +03:00
Ruslan Ermilov
ee9c61b89b gRPC: WINDOW_UPDATE after END_STREAM handling (ticket #1797).
As per https://tools.ietf.org/html/rfc7540#section-6.9,
WINDOW_UPDATE received after a frame with the END_STREAM flag
should be handled and not treated as an error.
2020-04-23 15:10:26 +03:00
Ruslan Ermilov
4c8abb84e3 gRPC: RST_STREAM(NO_ERROR) handling (ticket #1792).
As per https://tools.ietf.org/html/rfc7540#section-8.1,

: A server can send a complete response prior to the client
: sending an entire request if the response does not depend on
: any portion of the request that has not been sent and
: received.  When this is true, a server MAY request that the
: client abort transmission of a request without error by
: sending a RST_STREAM with an error code of NO_ERROR after
: sending a complete response (i.e., a frame with the
: END_STREAM flag).  Clients MUST NOT discard responses as a
: result of receiving such a RST_STREAM, though clients can
: always discard responses at their discretion for other
: reasons.

Previously, RST_STREAM(NO_ERROR) received from upstream after
a frame with the END_STREAM flag was incorrectly treated as an
error.  Now, a single RST_STREAM(NO_ERROR) is properly handled.

This fixes problems observed with modern grpc-c [1], as well
as with the Go gRPC module.

[1] https://github.com/grpc/grpc/pull/1661
2020-04-23 15:10:24 +03:00
Ruslan Ermilov
8c0a49472c Version bump. 2020-04-23 15:10:21 +03:00
Vladimir Homutov
ed506f8e15 TODOs cleanup in transport.
We always generate stream frames that have length. The 'len' member is used
during parsing incoming frames and can be safely ignored when generating
output.
2020-04-23 12:25:00 +03:00
Vladimir Homutov
936f577967 Retired the ngx_quic_parse_int_multi() function.
It used variable-length arguments what is not really necessary.
2020-04-23 12:10:56 +03:00
Vladimir Homutov
e34161c3d5 Removed support of drafts older than currently latest 27. 2020-04-23 11:50:20 +03:00
Vladimir Homutov
26b7056972 Added proper handling of connection close phases.
There are following flags in quic connection:

closing  - true, when a connection close is initiated, for whatever reason
draining - true, when a CC frame is received from peer

The following state machine is used for closing:

 +------------------+
 |       I/HS/AD    |
 +------------------+
 |        |       |
 |        |       V
 |        |   immediate close initiated:
 |        |     reasons: close by top-level protocol, fatal error
 |        |     + sends CC (probably with app-level message)
 |        |     + starts close_timer: 3 * PTO (current probe timeout)
 |        |       |
 |        |       V
 |        |   +---------+  - Reply to input with CC (rate-limited)
 |        |   | CLOSING |  - Close/Reset all streams
 |        |   +---------+
 |        |       |    |
 |        V       V    |
 |       receives CC   |
 |          |          |
idle        |          |
timer       |          |
 |          V          |
 |      +----------+   |  - MUST NOT send anything (MAY send a single CC)
 |      | DRAINING |   |  - if not already started, starts close_timer: 3 * PTO
 |      +----------+   |  - if not already done, close all streams
 |          |          |
 |          |          |
 |       close_timer fires
 |          |
 V          V
 +------------------------+
 |       CLOSED           | - clean up all the resources, drop connection
 +------------------------+   state completely

The ngx_quic_close_connection() function gets an "rc" argument, that signals
reason of connection closing:
    NGX_OK    - initiated by application (i.e. http/3), follow state machine
    NGX_DONE  - timedout (while idle or draining)
    NGX_ERROR - fatal error, destroy connection immediately

The PTO calculations are not yet implemented, hardcoded value of 5s is used.
2020-04-23 13:41:08 +03:00
Vladimir Homutov
c8edca3137 Refactored ngx_quic_close_connection().
The function is split into three:
    ngx_quic_close_connection() itself cleans up all core nginx things
    ngx_quic_close_quic()  deals with everything inside c->quic
    ngx_quic_close_streams() deals with streams cleanup

The quic and streams cleanup functions may return NGX_AGAIN, thus signalling
that cleanup is not ready yet, and the close cannot continue to next step.
2020-04-23 11:15:44 +03:00
Sergey Kandaurov
37b95d545c HTTP/3: directives with limited values converted to post handler.
The purpose is to show a precise line number with an invalid value.
2020-04-22 15:59:19 +03:00
Sergey Kandaurov
89bba9bf7d HTTP/3: bytes holding directives changed to ngx_conf_set_size_slot.
This allows to specify directive values with measurement units.
2020-04-22 15:48:39 +03:00
Sergey Kandaurov
db90ddcb9e Improved ngx_quic_build_int() code and readability.
The function now generates somewhat shorter assembler after inlining.
2020-04-22 14:52:16 +03:00
Roman Arutyunyan
9275f06a57 Fixed QUIC buffer consumption in send_chain(). 2020-04-21 17:52:32 +03:00
Roman Arutyunyan
400eb1b628 HTTP/3: fixed encoding variable-length integers. 2020-04-21 17:11:49 +03:00
Vladimir Homutov
f503658484 Fixed memory leak with reordered stream frames. 2020-04-20 18:32:46 +03:00
Roman Arutyunyan
10bda6e11b Fixed includes in quic headers. 2020-04-21 12:06:24 +03:00
Vladimir Homutov
07699053c0 Added MAX_STREAM_DATA stub handler.
Currently sending code is ignoring this.
2020-04-20 17:18:04 +03:00
Vladimir Homutov
baacacd845 Respecting maximum packet size.
The header size macros for long and short packets were fixed to provide
correct values in bytes.

Currently the sending code limits frames so they don't exceed max_packet_size.
But it does not account the case when a single frame can exceed the limit.

As a result of this patch, big payload (CRYPTO and STREAM) will be split
into a number of smaller frames that fit into advertised max_packet_size
(which specifies final packet size, after encryption).
2020-04-20 22:25:22 +03:00
Vladimir Homutov
67aa3b9191 Removed source/destination swap from the function creating header.
The function now creates a header according to fileds provided in the "pkt"
argument without applying any logic regarding sending side.
2020-04-20 12:12:17 +03:00
Sergey Kandaurov
fa264b46b1 Revert "Rejecting new connections with non-zero Initial packet."
chrome-unstable 83.0.4103.7 starts with Initial packet number 1.

I couldn't find a proper explanation besides this text in quic-transport:
    An endpoint MAY skip packet numbers when sending
    packets to detect this (Optimistic ACK Attack) behavior.
2020-04-17 12:01:45 +03:00
Vladimir Homutov
7288ac4862 Fixed error descriptions.
The check for array bound is done inside function that returns error
description.  Missing initialization element is added.
2020-04-16 16:54:22 +03:00
Vladimir Homutov
d8ab79f6db Removed outdated TODO.
If required, frame handler can invoke output itself.  There is no need to
call output directly in the payload handler, queuing is enough.
2020-04-16 13:28:43 +03:00
Vladimir Homutov
f901747f29 Added handling of incorrect values in TP configuration.
Some parameters have minimal/maximum values defined by standard.
2020-04-16 12:17:41 +03:00
Sergey Kandaurov
df01c0c13c Parsing of truncated packet numbers.
For sample decoding algorithm, see quic-transport-27#appendix-A.
2020-04-16 12:46:48 +03:00
Vladimir Homutov
29b6ad00a2 Added primitive flow control mechanisms.
+ MAX_STREAM_DATA frame is sent when recv() is performed on stream
   The new value is a sum of total bytes received by stream + free
   space in a buffer;

   The sending of MAX_STREM_DATA frame in response to STREAM_DATA_BLOCKED
   frame is adjusted to follow the same logic as above.

 + MAX_DATA frame is sent when total amount of received data is 2x
   of current limit.  The limit is doubled.

 + Default values of transport parameters are adjusted to more meaningful
   values:

   initial stream limits are set to quic buffer size instead of
   unrealistically small 255.

   initial max data is decreased to 16 buffer sizes, in an assumption that
   this is enough for a relatively short connection, instead of randomly
   chosen big number.

All this allows to initiate a stable flow of streams that does not block
on stream/connection limits (tested with FF 77.0a1 and 100K requests)
2020-04-15 18:54:03 +03:00