Commit graph

6912 commits

Author SHA1 Message Date
Vladimir Homutov
d39920689b Fixed frame retransmissions.
It was possible that retransmit timer was not set after the first
retransmission attempt, due to ngx_quic_retransmit() did not set
wait time properly, and the condition in retransmit handler was incorrect.
2020-05-18 13:54:35 +03:00
Vladimir Homutov
7d4864b89a Removed outdated debug. 2020-05-14 18:10:53 +03:00
Vladimir Homutov
c18864a097 Fixed a typo. 2020-05-14 17:22:29 +03:00
Sergey Kandaurov
7005f46678 README: Retry support, protocol error messages implemented. 2020-05-14 16:33:46 +03:00
Vladimir Homutov
2b8786afe8 Fixed time comparison. 2020-05-12 18:45:44 +03:00
Vladimir Homutov
685b42cef6 Added tests for connection id lengths in initial packet. 2020-05-14 14:49:28 +03:00
Vladimir Homutov
aa4f97dd73 Discard packets without fixed bit or reserved bits set.
Section 17.2 and 17.3 of QUIC transport:

Fixed bit: Packets containing a zero value for this bit are not
valid packets in this version and MUST be discarded.

Reserved bit: An endpoint MUST treat receipt of a packet that has
a non-zero value for these bits, after removing both packet and
header protection, as a connection error of type PROTOCOL_VIOLATION.
2020-05-14 01:06:45 +03:00
Vladimir Homutov
b507229c73 Added generation of CC frames with error on connection termination.
When an error occurs, then c->quic->error field may be populated
with an appropriate error code, and the CONNECTION CLOSE frame will be
sent to the peer before the connection is closed.  Otherwise, the error
treated as internal and INTERNAL_ERROR code is sent.

The pkt->error field is populated by functions processing packets to
indicate an error when it does not fit into pass/fail return status.
2020-05-14 15:54:45 +03:00
Sergey Kandaurov
4d3b28b39c Address validation using NEW_TOKEN frame. 2020-05-14 15:47:24 +03:00
Sergey Kandaurov
fbff14f583 Address validation using Retry packets.
The behaviour is toggled with the new directive "quic_retry on|off".
QUIC token construction is made suitable for issuing with NEW_TOKEN.
2020-05-14 15:47:18 +03:00
Sergey Kandaurov
92324d157c Server CID change refactored. 2020-05-13 18:34:34 +03:00
Sergey Kandaurov
b6e8c1b542 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
95ff5f6be4 Removed redundant long packet type checks. 2020-05-09 17:41:07 +03:00
Sergey Kandaurov
a05371cf9e Removed redundant SSL_do_handshake call before any handshake data. 2020-05-09 17:39:47 +03:00
Vladimir Homutov
72b6655e9c 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
8e16e4eff5 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
Sergey Kandaurov
04ba271d3e 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
2c62f443a9 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
76ef3c1768 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
5fc7d63f80 Mention quic branch in README. 2020-04-30 15:59:14 +03:00
Sergey Kandaurov
7a34d6e74a Configure: unbreak with old OpenSSL, --with-http_v3_module added. 2020-04-30 15:47:43 +03:00
Vladimir Homutov
8abc8b130f 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
675ec33c5b 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
390ffc92f2 Renamed retransmit event object in preparation for retry support. 2020-04-29 14:59:21 +03:00
Sergey Kandaurov
58dcabc2be Server CID change. 2020-04-28 18:24:01 +03:00
Sergey Kandaurov
90bd619f81 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
dfc9c2dd14 Added README. 2020-04-28 18:16:13 +03:00
Roman Arutyunyan
b93e22b5fd Respect MAX_DATA and MAX_STREAM_DATA from QUIC client. 2020-04-28 16:37:32 +03:00
Roman Arutyunyan
fa1795919c QUIC basic congestion control. 2020-04-28 16:42:43 +03:00
Roman Arutyunyan
70e34b17c8 Fixed packet retransmission.
Previously frames in ctx->sent queue could be lost.
2020-04-24 17:20:37 +03:00
Roman Arutyunyan
e15adc3eb8 Assign connection number to every QUIC stream log. 2020-04-23 18:05:05 +03:00
Vladimir Homutov
ff7635070e 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
530342f5fe 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
f6306e8faf 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
Vladimir Homutov
3df104d74a 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
3a9bdecdcd 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
7727d103ff Removed support of drafts older than currently latest 27. 2020-04-23 11:50:20 +03:00
Vladimir Homutov
9268eb82e6 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
51a4a7cace 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
143642175b 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
b609fbb299 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
8da6bbe021 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
29f6610c6a Fixed QUIC buffer consumption in send_chain(). 2020-04-21 17:52:32 +03:00
Roman Arutyunyan
f5497fb4b2 HTTP/3: fixed encoding variable-length integers. 2020-04-21 17:11:49 +03:00
Vladimir Homutov
fddff472ae Fixed memory leak with reordered stream frames. 2020-04-20 18:32:46 +03:00
Roman Arutyunyan
9ad3701249 Fixed includes in quic headers. 2020-04-21 12:06:24 +03:00
Vladimir Homutov
52ee48aee1 Added MAX_STREAM_DATA stub handler.
Currently sending code is ignoring this.
2020-04-20 17:18:04 +03:00
Vladimir Homutov
034b7aa141 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
6b721fa123 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
5bd2c23508 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