Commit graph

6857 commits

Author SHA1 Message Date
Vladimir Homutov
fb07bd3fc1 Create new stream immediately on receiving new stream id.
Before the patch, full STREAM frame handling was delayed until the frame with
zero offset is received.  Only node in the streams tree was created.

This lead to problems when such stream was deleted, in particular, it had no
handlers set for read events.

This patch creates new stream immediately, but delays data delivery until
the proper offset will arrive. This is somewhat similar to how accept()
operation works.

The ngx_quic_add_stream() function is no longer needed and merged into stream
handler.  The ngx_quic_stream_input() now only handles frames for existing
streams and does not deal with stream creation.
2020-04-15 14:29:00 +03:00
Vladimir Homutov
a99a268a5d Free remaining frames on connection close.
Frames can still float in the following queues:

 - crypto frames reordering queues (one per encryption level)
 - moved crypto frames cleanup to the moment where all streams are closed
 - stream frames reordering queues (one per packet number namespace)
 - frames retransmit queues (one per packet number namespace)
2020-04-15 13:09:39 +03:00
Vladimir Homutov
a72ce93da9 Sorted functions and functions declarations. 2020-04-14 16:30:41 +03:00
Vladimir Homutov
0a59aa67e4 Added reordering support for STREAM frames.
Each stream node now includes incoming frames queue and sent/received counters
for tracking offset. The sent counter is not used, c->sent is used, not like
in crypto buffers, which have no connections.
2020-04-15 11:11:54 +03:00
Vladimir Homutov
30f51174ec Crypto buffer frames reordering.
If offset in CRYPTO frame doesn't match expected, following actions are taken:
    a) Duplicate frames or frames within [0...current offset] are ignored
    b) New data from intersecting ranges (starts before current_offset, ends
       after) is consumed
    c) "Future" frames are stored in a sorted queue (min offset .. max offset)

Once a frame is consumed, current offset is updated and the queue is inspected:
    we iterate the queue until the gap is found and act as described
    above for each frame.

The amount of data in buffered frames is limited by corresponding macro.

The CRYPTO and STREAM frame structures are now compatible: they share
the same set of initial fields.  This allows to have code that deals with
both of this frames.

The ordering layer now processes the frame with offset and invokes the
handler when it can organise an ordered stream of data.
2020-04-14 12:16:25 +03:00
Vladimir Homutov
6d8f571730 Cleaned up magic numbers in ngx_quic_output_frames(). 2020-04-13 14:57:58 +03:00
Vladimir Homutov
7a7ef3cbfb Rename types and variables used for packet number space.
Quote: Conceptually, a packet number space is the context in which a packet
       can be processed and acknowledged.

ngx_quic_namespace_t => ngx_quic_send_ctx_t
qc->ns               => qc->send_ctx
ns->largest          => send_ctx->largest_ack

The ngx_quic_ns(level) macro now returns pointer, not just index:
    ngx_quic_get_send_ctx(c->quic, level)

ngx_quic_retransmit_ns() => ngx_quic_retransmit()
ngx_quic_output_ns() => ngx_quic_output_frames()
2020-04-14 12:06:32 +03:00
Sergey Kandaurov
8acaa933af Merged with the default branch. 2020-04-14 19:35:20 +03:00
Maxim Dounin
c0570462f1 release-1.17.10 tag 2020-04-14 17:19:26 +03:00
Maxim Dounin
e59dc472db nginx-1.17.10-RELEASE 2020-04-14 17:19:26 +03:00
Maxim Dounin
50bb38eacc Updated OpenSSL used for win32 builds. 2020-04-14 15:15:16 +03:00
Roman Arutyunyan
3dc5ecbe69 HTTP/3: fixed reading request body. 2020-04-13 17:54:23 +03:00
Ruslan Ermilov
814df8f412 The new auth_delay directive for delaying unauthorized requests.
The request processing is delayed by a timer.  Since nginx updates
internal time once at the start of each event loop iteration, this
normally ensures constant time delay, adding a mitigation from
time-based attacks.

A notable exception to this is the case when there are no additional
events before the timer expires.  To ensure constant-time processing
in this case as well, we trigger an additional event loop iteration
by posting a dummy event for the next event loop iteration.
2020-04-08 01:02:17 +03:00
Vladimir Homutov
093f4f21b5 Added basic offset support in client CRYPTO frames.
The offset in client CRYPTO frames is tracked in c->quic->crypto_offset_in.
This means that CRYPTO frames with non-zero offset are now accepted making
possible to finish handshake with client certificates that exceed max packet
size (if no reordering happens).

The c->quic->crypto_offset field is renamed to crypto_offset_out to avoid
confusion with tracking of incoming CRYPTO stream.
2020-04-07 15:50:38 +03:00
Sergey Kandaurov
df34c84733 Fixed build with OpenSSL using old callbacks API. 2020-04-07 12:54:34 +03:00
Vladimir Homutov
88b9aed247 ACK ranges processing.
+ since number of ranges in unknown, provide a function to parse them once
   again in handler to avoid memory allocation

 + ack handler now processes all ranges, not only the first

 + ECN counters are parsed and saved into frame if present
2020-04-06 16:19:26 +03:00
Vladimir Homutov
c0c3a400ef Ignore non-yet-implemented frames.
Such frames are grouped together in a switch and just ignored, instead of
closing the connection  This may improve test coverage.  All such frames
require acknowledgment.
2020-04-06 11:16:45 +03:00
Vladimir Homutov
c025e2cf80 Added check for SSL_get_current_cipher() results.
The function may return NULL and result need to be checked before use.
2020-04-04 22:25:41 +03:00
Vladimir Homutov
97ebd69704 Added a bit more debugging in STREAM frame parser. 2020-04-06 11:17:14 +03:00
Vladimir Homutov
e9f4adf0b3 Do not set timers after the connection is closed.
The qc->closing flag is set when a connection close is initiated for the first
time.

No timers will be set if the flag is active.

TODO: this is a temporary solution to avoid running timer handlers after
connection (and it's pool) was destroyed.  It looks like currently we have
no clear policy of connection closing in regard to timers.
2020-04-04 22:27:29 +03:00
Sergey Kandaurov
d42d04baf6 Discarding Handshake packets if no Handshake keys yet.
Found with a previously received Initial packet with ACK only, which
instantiates a new connection but do not produce the handshake keys.

This can be triggered by a fairly well behaving client, if the server
stands behind a load balancer that stripped Initial packets exchange.

Found by F5 test suite.
2020-04-06 14:54:10 +03:00
Sergey Kandaurov
9c12453342 Rejecting new connections with non-zero Initial packet. 2020-04-06 14:54:10 +03:00
Sergey Kandaurov
4a03675be3 TLS Key Update in QUIC.
Old keys retention is yet to be implemented.
2020-04-06 14:54:08 +03:00
Sergey Kandaurov
bf825ce6cc Removed excessive debugging in QUIC packet creation.
While here, eliminated further difference in between.
2020-04-04 17:34:39 +03:00
Sergey Kandaurov
755dd33d97 Logging of packet numbers in QUIC packet creation. 2020-04-04 17:34:04 +03:00
Vladimir Homutov
dc3a60c8d9 Removed unneccesary milliseconds conversion. 2020-04-03 16:33:59 +03:00
Vladimir Homutov
7e1e892a8a Proper handling of packet number in header.
- fixed setting of largest received packet number.
 - sending properly truncated packet number
 - added support for multi-byte packet number
2020-04-03 14:02:16 +03:00
Sergey Kandaurov
3d9b7f1c8b Advertizing MAX_STREAMS (0x12) credit in advance.
This makes sending large number of bidirectional stream work within ngtcp2,
which doesn't bother sending optional STREAMS_BLOCKED when exhausted.

This also introduces tracking currently opened and maximum allowed streams.
2020-04-03 13:49:44 +03:00
Sergey Kandaurov
48608142a3 Fixed computing nonce again, by properly shifting packet number. 2020-04-03 13:49:40 +03:00
Vladimir Homutov
4b40730b18 Fixed missing propagation of need_ack flag from frames to packet. 2020-04-03 09:53:51 +03:00
Vladimir Homutov
58b439447e Fixed excessive push timer firing.
The timer is set when an output frame is generated; there is no need to arm
it after it was fired.
2020-04-02 14:53:01 +03:00
Sergey Kandaurov
9f9700d6e3 Fixed computing nonce by xoring all packet number bytes.
Previously, the stub worked only with pnl=0.
2020-04-02 11:40:25 +03:00
Vladimir Homutov
dc0b7674f1 Output buffering.
Currently, the output is called periodically, each 200 ms to invoke
ngx_quic_output() that will push all pending frames into packets.

TODO: implement flags a-là Nagle & co (NO_DELAY/NO_PUSH...)
2020-04-01 17:09:11 +03:00
Vladimir Homutov
41fca95d9a Implemented retransmission and retransmit queue.
All frames collected to packet are moved into a per-namespace send queue.
QUIC connection has a timer which fires on the closest max_ack_delay time.
The frame is deleted from the queue when a corresponding packet is acknowledged.

The NGX_QUIC_MAX_RETRANSMISSION is a timeout that defines maximum length
of retransmission of a frame.
2020-04-01 17:06:26 +03:00
Vladimir Homutov
7eac371881 Introduced packet namespace in QUIC connection.
The structure contains all data that is related to the namespace:
packet number and output queue (next patch).
2020-04-01 14:31:08 +03:00
Vladimir Homutov
82558fa46a Refactored QUIC secrets storage.
The quic->keys[4] array now contains secrets related to the corresponding
encryption level.  All protection-level functions get proper keys and do
not need to switch manually between levels.
2020-04-01 14:25:25 +03:00
Vladimir Homutov
38b5f39e8e Added missing debug description. 2020-04-01 17:21:52 +03:00
Sergey Kandaurov
56456e36fc TLS Early Data support. 2020-04-01 13:27:42 +03:00
Sergey Kandaurov
f68c876ca3 TLS Early Data key derivation support. 2020-04-01 13:27:42 +03:00
Sergey Kandaurov
e0e880bfab Sending HANDSHAKE_DONE just once with BoringSSL.
If early data is accepted, SSL_do_handshake() completes as soon as ClientHello
is processed.  SSL_in_init() will report the handshake is still in progress.
2020-04-01 13:27:42 +03:00
Sergey Kandaurov
21f4be001a QUIC packet padding to fulfil header protection sample demands. 2020-04-01 13:27:42 +03:00
Sergey Kandaurov
7d5fe69bb2 Improved SSL_do_handshake() error handling in QUIC.
It can either return a recoverable SSL_ERROR_WANT_READ or fatal errors.
2020-04-01 13:27:42 +03:00
Sergey Kandaurov
108bc03458 Style. 2020-04-01 13:27:41 +03:00
Vladimir Homutov
ed21279b6f Removed unused field from ngx_quic_header_t. 2020-03-31 13:13:12 +03:00
Sergey Kandaurov
6749f64f7f HTTP/3: http3 variable. 2020-03-28 18:41:31 +03:00
Sergey Kandaurov
536810e48b HTTP/3: static table cleanup. 2020-03-28 18:02:20 +03:00
Roman Arutyunyan
48a1eeb5c2 Parsing HTTP/3 request body. 2020-03-27 19:41:06 +03:00
Roman Arutyunyan
732e383dd1 Fixed handling QUIC stream eof.
Set r->pending_eof flag for a new QUIC stream with the fin bit.  Also, keep
r->ready set when r->pending_eof is set and buffer is empty.
2020-03-27 10:02:45 +03:00
Roman Arutyunyan
6bc0ecd946 Push QUIC stream frames in send() and cleanup handler. 2020-03-27 19:08:24 +03:00
Roman Arutyunyan
50e32ed41d Chunked response body in HTTP/3. 2020-03-27 19:46:54 +03:00