Commit Graph

5985 Commits

Author SHA1 Message Date
Maxim Dounin
4056ce4f4e HTTP/2: invalid connection preface logging (ticket #1981).
Previously, invalid connection preface errors were only logged at debug
level, providing no visible feedback, in particular, when a plain text
HTTP/2 listening socket is erroneously used for HTTP/1.x connections.
Now these are explicitly logged at the info level, much like other
client-related errors.
2020-05-25 18:33:42 +03:00
Sergey Kandaurov
9b87626b0b Fixed format specifiers. 2020-05-23 15:53:08 +03:00
Roman Arutyunyan
5727f9a1e0 OCSP: certificate status cache.
When enabled, certificate status is stored in cache and is used to validate
the certificate in future requests.

New directive ssl_ocsp_cache is added to configure the cache.
2020-05-22 17:25:27 +03:00
Roman Arutyunyan
60438ae395 SSL: client certificate validation with OCSP (ticket #1534).
OCSP validation for client certificates is enabled by the "ssl_ocsp" directive.
OCSP responder can be optionally specified by "ssl_ocsp_responder".

When session is reused, peer chain is not available for validation.
If the verified chain contains certificates from the peer chain not available
at the server, validation will fail.
2020-05-22 17:30:12 +03:00
Roman Arutyunyan
aa94ee82f6 OCSP stapling: iterate over all responder addresses.
Previously only the first responder address was used per each stapling update.
Now, in case of a network or parsing error, next address is used.

This also fixes the issue with unsupported responder address families
(ticket #1330).
2020-05-22 20:35:05 +03:00
Roman Arutyunyan
abdb9aebc6 OCSP stapling: keep extra chain in the staple object. 2020-05-17 14:24:35 +03:00
Roman Arutyunyan
097d8a87b3 HTTP/3: reallocate strings inserted into the dynamic table.
They should always be allocated from the main QUIC connection pool.
2020-05-14 16:02:32 +03:00
Roman Arutyunyan
94764fda6e Fixed client buffer reallocation for HTTP/3.
Preserving pointers within the client buffer is not needed for HTTP/3 because
all data is either allocated from pool or static.  Unlike with HTTP/1, data
typically cannot be referenced directly within the client buffer.  Trying to
preserve NULLs or external pointers lead to broken pointers.

Also, reverted changes in ngx_http_alloc_large_header_buffer() not relevant
for HTTP/3 to minimize diff to mainstream.
2020-05-19 16:20:33 +03:00
Roman Arutyunyan
d6b6b6dfc5 Fixed $request_length for HTTP/3.
New field r->parse_start is introduced to substitute r->request_start and
r->header_name_start for request length accounting.  These fields only work for
this purpose in HTTP/1 because HTTP/1 request line and header line start with
these values.

Also, error logging is now fixed to output the right part of the request.
2020-05-19 15:47:37 +03:00
Roman Arutyunyan
d25937c2b5 HTTP/3: restricted symbols in header names.
As per HTTP/3 draft 27, a request or response containing uppercase header
field names MUST be treated as malformed.  Also, existing rules applied
when parsing HTTP/1 header names are also applied to HTTP/3 header names:

- null character is not allowed
- underscore character may or may not be treated as invalid depending on the
  value of "underscores_in_headers"
- all non-alphanumeric characters with the exception of '-' are treated as
  invalid

Also, the r->locase_header field is now filled while parsing an HTTP/3
header.

Error logging for invalid headers is fixed as well.
2020-05-19 15:34:00 +03:00
Roman Arutyunyan
6abb50658f HTTP/3: split header parser in two functions.
The first one parses pseudo-headers and is analagous to the request line
parser in HTTP/1.  The second one parses regular headers and is analogous to
the header parser in HTTP/1.

Additionally, error handling of client passing malformed uri is now fixed.
2020-05-19 15:29:10 +03:00
Roman Arutyunyan
d69f678e9c HTTP/3: move body parser call out of ngx_http_parse_chunked().
The function ngx_http_parse_chunked() is also called from the proxy module to
parse the upstream response.  It should always parse HTTP/1 body in this case.
2020-05-14 14:49:53 +03:00
Roman Arutyunyan
1c54340e0a HTTP/3: prevent array access by negative index for unknown streams.
Currently there are no such streams, but the function
ngx_http_v3_get_uni_stream() supports them.
2020-05-19 15:41:41 +03:00
Vladimir Homutov
74564bdd0d Style.
Rephrased error message and removed trailing space.  Long comments were
shortened/rephrased.
2020-05-21 15:48:39 +03:00
Vladimir Homutov
57696b56e9 Added sending of extra CONNECTION_CLOSE frames.
According to quic-transport draft 28 section 10.3.1:

   When sending CONNECTION_CLOSE, the goal is to ensure that the peer
   will process the frame.  Generally, this means sending the frame in a
   packet with the highest level of packet protection to avoid the
   packet being discarded.  After the handshake is confirmed (see
   Section 4.1.2 of [QUIC-TLS]), an endpoint MUST send any
   CONNECTION_CLOSE frames in a 1-RTT packet.  However, prior to
   confirming the handshake, it is possible that more advanced packet
   protection keys are not available to the peer, so another
   CONNECTION_CLOSE frame MAY be sent in a packet that uses a lower
   packet protection level.
2020-05-22 18:14:35 +03:00
Vladimir Homutov
76605fa07a Added more context to CONNECTION CLOSE frames.
Now it is possible to specify frame type that caused an error
and a human-readable reason phrase.
2020-05-22 18:08:02 +03:00
Vladimir Homutov
4444320473 Fixed retransmission of frames after closing connection.
Frames in sent queues are discarded, as no acknowledgment is expected
if the connection is closing.
2020-05-21 15:41:01 +03:00
Vladimir Homutov
7e0314de24 Avoided excessive definitions for connection state.
There is no need in a separate type for the QUIC connection state.
The only state not found in the SSL library is NGX_QUIC_ST_UNAVAILABLE,
which is actually a flag used by the ngx_quic_close_quic() function
to prevent cleanup of uninitialized connection.
2020-05-21 15:38:52 +03:00
Sergey Kandaurov
51e4e31a8d Assorted fixes.
Found by Clang Static Analyzer.
2020-05-20 15:36:24 +03:00
Vladimir Homutov
04efd355aa Avoid retransmitting of packets with discarded keys.
Sections 4.10.1 and 4.10.2 of quic transport describe discarding of initial
and handshake keys.  Since the keys are discarded, we no longer need
to retransmit packets and corresponding queues should be emptied.

This patch removes previously added workaround that did not require
acknowledgement for initial packets, resulting in avoiding retransmission,
which is wrong because a packet could be lost and we have to retransmit it.
2020-05-18 13:54:53 +03:00
Vladimir Homutov
0041c3f6b7 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
92df22200e Removed outdated debug. 2020-05-14 18:10:53 +03:00
Vladimir Homutov
6f7477f6c6 Fixed time comparison. 2020-05-12 18:45:44 +03:00
Vladimir Homutov
5ccda6882e Added tests for connection id lengths in initial packet. 2020-05-14 14:49:28 +03:00
Vladimir Homutov
d4f9bba111 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
cb316c5f58 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
9b1800d09a Address validation using NEW_TOKEN frame. 2020-05-14 15:47:24 +03:00
Sergey Kandaurov
ad2289e70e 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
d35eebede2 Server CID change refactored. 2020-05-13 18:34:34 +03:00
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
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
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
Vladimir Homutov
2e2d1843c3 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
001b81af88 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
53d47318c5 Sorted functions and functions declarations. 2020-04-14 16:30:41 +03:00
Vladimir Homutov
9542c975b7 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
081682cd3c 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
76e99f668d Cleaned up magic numbers in ngx_quic_output_frames(). 2020-04-13 14:57:58 +03:00
Vladimir Homutov
fbf6494f5f 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
987a1216e7 Merged with the default branch. 2020-04-14 19:35:20 +03:00
Roman Arutyunyan
b77fd3dc58 HTTP/3: fixed reading request body. 2020-04-13 17:54:23 +03:00
Ruslan Ermilov
b82c08f610 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
c64a3939e4 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
f540602ad2 Fixed build with OpenSSL using old callbacks API. 2020-04-07 12:54:34 +03:00
Vladimir Homutov
35878c3796 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
1c9ddadd76 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
757b3e7bcf 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
61aa190cfb Added a bit more debugging in STREAM frame parser. 2020-04-06 11:17:14 +03:00
Vladimir Homutov
5b41275219 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
3f3315aea6 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
cc704a8c31 Rejecting new connections with non-zero Initial packet. 2020-04-06 14:54:10 +03:00
Sergey Kandaurov
1381982aaa TLS Key Update in QUIC.
Old keys retention is yet to be implemented.
2020-04-06 14:54:08 +03:00
Sergey Kandaurov
3b77fb705b Removed excessive debugging in QUIC packet creation.
While here, eliminated further difference in between.
2020-04-04 17:34:39 +03:00
Sergey Kandaurov
671ed4b3b1 Logging of packet numbers in QUIC packet creation. 2020-04-04 17:34:04 +03:00
Vladimir Homutov
4cfc98c63f Removed unneccesary milliseconds conversion. 2020-04-03 16:33:59 +03:00
Vladimir Homutov
b3300b5220 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
b4719e8ea4 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
569da72e4b Fixed computing nonce again, by properly shifting packet number. 2020-04-03 13:49:40 +03:00
Vladimir Homutov
723c276a7b Fixed missing propagation of need_ack flag from frames to packet. 2020-04-03 09:53:51 +03:00
Vladimir Homutov
932bfe7b36 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
9c8a7a52e1 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
01bddf4533 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
7b1a3df37c 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
d7eeb2e30b 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
9595417396 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
c6859361e3 Added missing debug description. 2020-04-01 17:21:52 +03:00
Sergey Kandaurov
6abff71fc4 TLS Early Data support. 2020-04-01 13:27:42 +03:00
Sergey Kandaurov
140a89ce01 TLS Early Data key derivation support. 2020-04-01 13:27:42 +03:00
Sergey Kandaurov
22671b37e3 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
833a28244f QUIC packet padding to fulfil header protection sample demands. 2020-04-01 13:27:42 +03:00
Sergey Kandaurov
e9d67086c7 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
86029005a5 Style. 2020-04-01 13:27:41 +03:00
Vladimir Homutov
c3b7927e24 Removed unused field from ngx_quic_header_t. 2020-03-31 13:13:12 +03:00
Sergey Kandaurov
4502e5b1e9 HTTP/3: http3 variable. 2020-03-28 18:41:31 +03:00
Sergey Kandaurov
7a0b840c51 HTTP/3: static table cleanup. 2020-03-28 18:02:20 +03:00
Roman Arutyunyan
fa1e1beadc Parsing HTTP/3 request body. 2020-03-27 19:41:06 +03:00
Roman Arutyunyan
84a7835015 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
89a6a4f198 Push QUIC stream frames in send() and cleanup handler. 2020-03-27 19:08:24 +03:00
Roman Arutyunyan
80a38580bd Chunked response body in HTTP/3. 2020-03-27 19:46:54 +03:00
Roman Arutyunyan
81f7cff632 Fixed buffer overflow. 2020-03-27 15:50:42 +03:00
Sergey Kandaurov
3fbdc04072 Unbreak sending CONNECTION_CLOSE from the send_alert callback. 2020-03-27 12:52:08 +03:00
Vladimir Homutov
41a8b8d392 Merged ngx_quic_send_packet() into ngx_quic_send_frames().
This allows to avoid extra allocation and use two static buffers instead.
Adjusted maximum paket size calculation: need to account a tag.
2020-03-26 18:29:38 +03:00
Vladimir Homutov
7d408f1bba Got rid of memory allocation in decryption.
Static buffers are used instead in functions where decryption takes place.

The pkt->plaintext points to the beginning of a static buffer.
The pkt->payload.data points to decrypted data actual start.
2020-03-26 16:54:46 +03:00
Vladimir Homutov
7c6e6426c6 Logging cleanup.
pool->log is replaced with pkt->log or explicit argument passing where
possible.
2020-03-26 13:54:49 +03:00
Roman Arutyunyan
d71df64e9a QUIC frames reuse. 2020-03-25 23:40:50 +03:00
Vladimir Homutov
715d8a250b Removed memory allocations from encryption code.
+ ngx_quic_encrypt():
     - no longer accepts pool as argument
     - pkt is 1st arg
     - payload is passed as pkt->payload
     - performs encryption to the specified static buffer

 + ngx_quic_create_long/short_packet() functions:
    - single buffer for everything, allocated by caller
    - buffer layout is: [ ad | payload | TAG ]
      the result is in the beginning of buffer with proper length
    - nonce is calculated on stack
    - log is passed explicitly, pkt is 1st arg
    - no more allocations inside

 + ngx_quic_create_long_header():
    - args changed: no need to pass str_t

 + added ngx_quic_create_short_header()
2020-03-26 12:11:50 +03:00
Roman Arutyunyan
bcd54c2643 Fixed QUIC stream insert and find. 2020-03-25 14:05:40 +03:00
Roman Arutyunyan
dbf1b41cfb Simplifed handling HTTP/3 streams. 2020-03-25 12:14:24 +03:00
Roman Arutyunyan
95f439630b Safe QUIC stream creation. 2020-03-25 12:56:21 +03:00
Roman Arutyunyan
a0a2e0de1d When closing a QUIC connection, wait for all streams to finish.
Additionally, streams are now removed from the tree in cleanup handler.
2020-03-24 18:05:45 +03:00
Roman Arutyunyan
f75e4e3fef Removed ngx_quic_stream_node_t.
Now ngx_quic_stream_t is directly inserted into the tree.
2020-03-24 16:38:03 +03:00
Roman Arutyunyan
061a42d966 Implemented eof in QUIC streams. 2020-03-24 13:49:42 +03:00
Vladimir Homutov
c5505648d7 Fixed log initialization.
Should be done after memzero.
2020-03-25 19:42:00 +03:00
Sergey Kandaurov
685e7d1451 Advertise our max_idle_timeout in transport parameters.
So we can easily tune how soon client would decide to close a connection.
2020-03-24 22:12:52 +03:00
Sergey Kandaurov
d8d42e29e7 QUIC streams don't need filter_need_in_memory after 7f0981be07c4.
Now they inherit c->ssl always enabled from the main connection,
which makes r->main_filter_need_in_memory set for them.
2020-03-24 19:17:57 +03:00
Vladimir Homutov
8c26e1d148 Logging cleanup.
+ Client-related errors (i.e. parsing) are done at INFO level
 + c->log->action is updated through the process of receiving, parsing.
   handling packet/payload and generating frames/output.
2020-03-24 17:03:39 +03:00
Vladimir Homutov
780f4f660c Added QUIC version check for sending HANDSHAKE_DONE frame. 2020-03-24 12:15:39 +03:00
Vladimir Homutov
57544f7589 Implemented sending HANDSHAKE_DONE frame after handshake.
This makes it possible to switch to draft 27 by default.
2020-03-24 11:59:14 +03:00
Sergey Kandaurov
f20af3dabc Fixed client certificate verification.
For ngx_http_process_request() part to work, this required to set both
r->http_connection->ssl and c->ssl on a QUIC stream.  To avoid damaging
global SSL object, ngx_ssl_shutdown() is managed to ignore QUIC streams.
2020-03-23 20:48:34 +03:00
Roman Arutyunyan
5ac5e51fdf Respect QUIC max_idle_timeout. 2020-03-23 21:20:20 +03:00
Roman Arutyunyan
9975b088bb Allow ngx_queue_frame() to insert frame in the front.
Previously a frame could only be inserted after the first element of the list.
2020-03-23 19:42:09 +03:00
Roman Arutyunyan
ede2656c60 Support for HTTP/3 ALPN.
This is required by Chrome.
2020-03-23 19:26:24 +03:00
Roman Arutyunyan
77a4c2d172 Put zero in 'First ACK Range' when acknowledging one packet.
This fixes Chrome CONNECTION_ID_LIMIT_ERROR with the reason:
"Underflow with first ack block length 2 largest acked is 1".
2020-03-23 15:32:24 +03:00
Roman Arutyunyan
f4562d7ed9 Avoid using QUIC connection after CONNECTION_CLOSE. 2020-03-23 19:19:44 +03:00
Roman Arutyunyan
3fa1dec9c7 Better flow control and buffering for QUIC streams. 2020-03-23 15:49:31 +03:00
Roman Arutyunyan
72b0a1b32a Limit output QUIC packets with client max_packet_size.
Additionally, receive larger packets than 512 bytes.
2020-03-23 18:47:17 +03:00
Sergey Kandaurov
280c18bdce Fixed received ACK fields order in debug logging. 2020-03-23 18:20:42 +03:00
Vladimir Homutov
5018d9eecc Connection states code cleanup.
+ ngx_quic_init_ssl_methods() is no longer there, we setup methods on SSL
   connection directly.

 + the handshake_handler is actually a generic quic input handler

 + updated c->log->action and debug to reflect changes and be more informative

 + c->quic is always set in ngx_quic_input()

 + the quic connection state is set by the results of SSL_do_handshake();
2020-03-23 14:53:04 +03:00
Vladimir Homutov
b3129b46f6 Skip unknown transport parameters. 2020-03-23 12:57:24 +03:00
Vladimir Homutov
6a3a0ee19f Add unsupported version into log.
This makes it easier to understand what client wants.
2020-03-23 10:57:28 +03:00
Vladimir Homutov
4490aefa70 Added processing of client transport parameters.
note:
 + parameters are available in SSL connection since they are obtained by ssl
   stack

quote:
   During connection establishment, both endpoints make authenticated
   declarations of their transport parameters.  These declarations are
   made unilaterally by each endpoint.

and really, we send our parameters before we read client's.

no handling of incoming parameters is made by this patch.
2020-03-21 20:51:59 +03:00
Sergey Kandaurov
de095d5f1d Fixed CRYPTO offset generation. 2020-03-22 12:15:54 +03:00
Sergey Kandaurov
ccb0049e3f Closing connection on NGX_QUIC_FT_CONNECTION_CLOSE. 2020-03-22 11:35:15 +03:00
Vladimir Homutov
63e6c9349e Implemented parsing of remaining frame types. 2020-03-21 20:49:55 +03:00
Sergey Kandaurov
2af37e507d Fixed parsing NGX_QUIC_FT_CONNECTION_CLOSE. 2020-03-21 19:45:24 +03:00
Sergey Kandaurov
79e49c2a16 Fixed buffer overrun in create_transport_params() with -24.
It writes 16-bit prefix as designed, but length calculation assumed varint.
2020-03-21 19:22:39 +03:00
Sergey Kandaurov
4764ef1590 Fixed build with macOS's long long abomination. 2020-03-21 18:44:10 +03:00
Roman Arutyunyan
0f77eac8af Removed unused variable. 2020-03-20 23:49:42 +03:00
Vladimir Homutov
b26d5deae4 Removed unused variable. 2020-03-20 20:39:41 +03:00
Vladimir Homutov
21b6854bfe Added checks for permitted frame types.
+ cleanup in macros for packet types
 + some style fixes in quic_transport.h (case, indentation)
2020-03-20 20:03:44 +03:00
Vladimir Homutov
1d35d0f31e Fixed parsing of CONNECTION CLOSE2 frames.
The "frame_type" field is not passed in case of 0x1d frame.
2020-03-20 15:14:00 +03:00
Vladimir Homutov
6565860bd8 Added parsing of CONNECTION_CLOSE2 frame (0x1D).
The difference is that error code refers to application namespace, i.e.
quic error names cannot be used to convert it to string.
2020-03-20 14:50:05 +03:00
Vladimir Homutov
4096676897 Adedd the http "quic" variable.
The value is literal "quic" for requests passed over HTTP/3, and empty string
otherwise.
2020-03-20 12:44:45 +03:00
Vladimir Homutov
30de0ca52d Configurable transport parameters.
- integer parameters can be configured using the following directives:

    quic_max_idle_timeout
    quic_max_ack_delay
    quic_max_packet_size
    quic_initial_max_data
    quic_initial_max_stream_data_bidi_local
    quic_initial_max_stream_data_bidi_remote
    quic_initial_max_stream_data_uni
    quic_initial_max_streams_bidi
    quic_initial_max_streams_uni
    quic_ack_delay_exponent
    quic_active_migration
    quic_active_connection_id_limit

 - only following parameters are actually sent:

    active_connection_id_limit
    initial_max_streams_uni
    initial_max_streams_bidi
    initial_max_stream_data_bidi_local
    initial_max_stream_data_bidi_remote
    initial_max_stream_data_uni

 (other parameters are to be added into ngx_quic_create_transport_params()
  function as needed, should be easy now)

 - draft 24 and draft 27 are now supported
   (at compile-time using quic_version macro)
2020-03-20 13:47:44 +03:00
Roman Arutyunyan
5f9b188c21 Reset QUIC timeout on every datagram. 2020-03-19 21:46:28 +03:00
Roman Arutyunyan
3ba0d03a6e Double MAX_STREAMS on STREAMS_BLOCKED. 2020-03-20 10:14:58 +03:00
Roman Arutyunyan
ea6809ac73 Fixed ACKs to packet numbers greater than 63. 2020-03-20 09:23:31 +03:00
Sergey Kandaurov
2710df57c7 Fixed specifiers in "quic packet length" logging. 2020-03-19 17:33:36 +03:00
Sergey Kandaurov
06294ab67a Fixed build. 2020-03-19 17:22:43 +03:00
Vladimir Homutov
1b4b8af624 The ngx_quic_frame_len() function is not really needed. 2020-03-19 14:59:55 +03:00
Vladimir Homutov
18ce6d5ebf Added boundaries checks into frame parser.
The ngx_quic_parse_frame() functions now has new 'pkt' argument: the packet
header of a currently processed frame.  This allows to log errors/debug
closer to reasons and perform additional checks regarding possible frame
types.  The handler only performs processing of good frames.


A number of functions like read_uint32(), parse_int[_multi] probably should
be implemented as a macro, but currently it is better to have them as
functions for simpler debugging.
2020-03-19 17:07:12 +03:00
Roman Arutyunyan
4cbfc07394 Send a FIN frame when QUIC stream is closed. 2020-03-19 15:34:35 +03:00
Roman Arutyunyan
8ad2707d4f Fixed header creation for header_only responses in HTTP/3. 2020-03-19 15:03:09 +03:00
Sergey Kandaurov
31e794f0ad MAX_DATA frame parser/handler. 2020-03-18 23:26:26 +03:00
Vladimir Homutov
33d8317dd5 Added parsing of STREAMS BLOCKED frames.
While there, added hex prefix for debug to avoid frame type confusion.
2020-03-19 11:15:43 +03:00
Sergey Kandaurov
6aa611c314 Implemented send_alert callback, CONNECTION_CLOSE writer.
The callback produces a CONNECTION_CLOSE frame, as per quic-tls-24#section-4.9.
2020-03-18 23:07:40 +03:00
Roman Arutyunyan
0561665873 Added copying addr_text to QUIC stream connections.
Now $remote_addr holds client address.
2020-03-18 20:28:28 +03:00
Roman Arutyunyan
e63accd7bd HTTP/3 $request_line variable. 2020-03-18 20:22:16 +03:00
Roman Arutyunyan
5aa8e519c9 Moved setting QUIC methods to runtime.
This allows listening to both https and http3 in the same server.
Also, the change eliminates the ssl_quic directive.
2020-03-18 16:37:16 +03:00
Vladimir Homutov
50f919cec4 Added parsing of RESET_STREAM and STOP_SENDING frames 2020-03-18 16:35:11 +03:00
Roman Arutyunyan
04d037b239 Fixed pointer increment while parsing HTTP/3 header. 2020-03-18 15:28:20 +03:00
Vladimir Homutov
2973465556 Implemented creation of server unidirectional streams.
The ngx_quic_create_stream() function is a generic function extracted from
the ngx_quic_handle_stream_frame() function.
2020-03-18 13:49:39 +03:00
Roman Arutyunyan
d36684447c Fixed HTTP/3 server stream creation. 2020-03-18 14:10:44 +03:00
Roman Arutyunyan
85430505fe Removed comment. 2020-03-18 14:09:50 +03:00
Roman Arutyunyan
01dc7445f0 Refactored HTTP/3 parser. 2020-03-18 13:46:35 +03:00
Vladimir Homutov
023dbc3cfb Style and handlers.
Cleanup in ngx_event_quic.c:
    + reorderded functions, structures
    + added missing prototypes
    + added separate handlers for each frame type
    + numerous indentation/comments/TODO fixes
    + removed non-implemented qc->state and corresponding enum;
        this requires deep thinking, stub was unused.
    + streams inside quic connection are now in own structure
2020-03-18 13:02:19 +03:00
Vladimir Homutov
23dc6a68a4 Extracted transport part of the code into separate file.
All code dealing with serializing/deserializing
is moved int srv/event/ngx_event_quic_transport.c/h file.

All macros for dealing with data are internal to source file.

The header file exposes frame types and error codes.

The exported functions are currently packet header parsers and writers
and frames parser/writer.

The ngx_quic_header_t structure is updated with 'log' member. This avoids
passing extra argument to parsing functions that need to report errors.
2020-03-18 12:58:27 +03:00
Vladimir Homutov
cd54c1cab7 Firefox fixes.
+ support for more than one initial packet
 + workaround for trailing zeroes in packet
 + ignore application data packet if no keys yet (issue in draft 27/ff nightly)
 + fixed PING frame parser
 + STREAM frames need to be acknowledged

The following HTTP configuration is used for firefox (v74):

http {

    ssl_certificate_key localhost.key;
    ssl_certificate localhost.crt;
    ssl_protocols TLSv1.2 TLSv1.3;

    server {
        listen 127.0.0.1:10368 reuseport http3;
        ssl_quic on;
        server_name  localhost;

        location / {
            return 200 "This-is-QUICK\n";
        }
    }
    server {
        listen 127.0.0.1:5555 ssl; # point the browser here
        server_name  localhost;
        location / {
            add_header Alt-Svc 'h3-24=":10368";ma=100';
            return 200 "ALT-SVC";
        }
    }
}
2020-03-17 14:10:37 +03:00
Vladimir Homutov
ca7943393e Fixed a typo with OpenSSL. 2020-03-16 19:42:57 +03:00
Vladimir Homutov
d0ebfa4cb9 Split transport and crypto parts into separate files.
New files:
    src/event/ngx_event_quic_protection.h
    src/event/ngx_event_quic_protection.c

The protection.h header provides interface to the crypto part of the QUIC:

2 functions to initialize corresponding secrets:

ngx_quic_set_initial_secret()
ngx_quic_set_encryption_secret()

and 2 functions to deal with packet processing:

ngx_quic_encrypt()
ngx_quic_decrypt()

Also, structures representing secrets are defined there.

All functions require SSL connection and a pool, only crypto operations
inside, no access to nginx connections or events.

Currently pool->log is used for the logging (instead of original c->log).
2020-03-16 19:00:47 +03:00
Vladimir Homutov
0d8984083b Added processing of CONNECTION CLOSE frames.
Contents is parsed and debug is output. No actions are taken.
2020-03-16 13:06:43 +03:00
Roman Arutyunyan
5399670fcc Temporary fix for header null-termination in HTTP/3. 2020-03-14 13:18:55 +03:00
Sergey Kandaurov
1ac31c01b4 Fixed header protection application with pn length > 1. 2020-03-14 03:15:09 +03:00
Roman Arutyunyan
11dfc1c943 Fixed sanitizer errors. 2020-03-13 20:44:32 +03:00
Vladimir Homutov
8f35d300ed Added check for initialized c->ssl before calling SSL shutdown. 2020-03-13 18:55:58 +03:00
Roman Arutyunyan
7739b6073b HTTP/3. 2020-03-13 19:36:33 +03:00
Roman Arutyunyan
365b77b587 Fixed infinite loop in ngx_quic_stream_send_chain(). 2020-03-13 18:30:37 +03:00
Roman Arutyunyan
a1ac82ca0f Implemented tracking offset in STREAM frames. 2020-03-13 18:29:50 +03:00
Roman Arutyunyan
dcb6aab460 Implemented ngx_quic_stream_send_chain() method.
- just call send in a loop
2020-03-13 15:56:10 +03:00
Vladimir Homutov
05d1464c68 Stream "connection" read/write methods. 2020-03-13 14:39:23 +03:00
Ruslan Ermilov
65ae8b3152 Auth basic: explicitly zero out password buffer. 2020-03-13 02:12:10 +03:00
Ruslan Ermilov
1688f575c2 Version bump. 2020-03-16 12:41:41 +03:00
Sergey Kandaurov
5bc8cd4044 Fix build. 2020-03-12 18:08:26 +03:00
Vladimir Homutov
21eaac9a3e Removed hardcoded CRYPTO and ACK frame sizes. 2020-03-12 14:23:27 +03:00
Vladimir Homutov
4f4f56f013 HTTP/QUIC interface reworked.
- events handling moved into src/event/ngx_event_quic.c
 - http invokes once ngx_quic_run() and passes stream callback
 (diff to original http_request.c is now minimal)

 - streams are stored in rbtree using ID as a key
 - when a new stream is registered, appropriate callback is called

 - ngx_quic_stream_t type represents STREAM and stored in c->qs
2020-03-12 16:54:43 +03:00
Vladimir Homutov
6bf6635d86 Initial parsing of STREAM frames. 2020-03-11 15:41:35 +03:00
Vladimir Homutov
0d10672137 Added support of multiple QUIC packets in single datagram.
- now NEW_CONNECTION_ID frames can be received and parsed

The packet structure is created in ngx_quic_input() and passed
to all handlers (initial, handshake and application data).

The UDP datagram buffer is saved as pkt->raw;
The QUIC packet is stored as pkt->data and pkt->len (instead of pkt->buf)
(pkt->len is adjusted after parsing headers to actual length)

The pkt->pos is removed, pkt->raw->pos is used instead.
2020-03-12 14:43:24 +03:00
Vladimir Homutov
0d1c27b580 Added more transport parameters.
Needed for client to start sending streams.
2020-03-11 15:43:23 +03:00
Sergey Kandaurov
9311e59443 Compatibility with BoringSSL revised QUIC encryption secret APIs.
See for details: https://boringssl.googlesource.com/boringssl/+/1e85905%5E!/
2020-03-11 21:53:02 +03:00
Sergey Kandaurov
df544ee47d Chacha20 header protection support with BoringSSL.
BoringSSL lacks EVP for Chacha20.  Here we use CRYPTO_chacha_20() instead.
2020-03-10 19:15:12 +03:00
Sergey Kandaurov
7e417544bb ChaCha20 / Poly1305 initial support. 2020-03-10 19:13:09 +03:00
Sergey Kandaurov
4b59999afe Using SSL cipher suite id to obtain cipher/digest, part 2.
Ciphers negotiation handling refactored into ngx_quic_ciphers().
2020-03-10 19:12:22 +03:00
Sergey Kandaurov
385408732e Fixed nonce in short packet protection. 2020-03-10 18:40:18 +03:00
Vladimir Homutov
c2afb5ec8a Generic payload handler for quic packets.
- added basic parsing of ACK, PING and PADDING frames on input
 - added preliminary parsing of SHORT headers

The ngx_quic_output() is now called after processing of each input packet.
Frames are added into output queue according to their level: inital packets
go ahead of handshake and application data, so they can be merged properly.

The payload handler is called from both new, handshake and applicataion data
handlers (latter is a stub).
2020-03-10 18:24:39 +03:00
Sergey Kandaurov
547a1a0159 Fixed header protection with negotiated cipher suite. 2020-03-05 20:05:40 +03:00
Sergey Kandaurov
ed0533c2c2 Initial packets are protected with AEAD_AES_128_GCM. 2020-03-05 19:49:49 +03:00
Sergey Kandaurov
b0f1302e7d Fixed write secret logging in set_encryption_secrets callback. 2020-03-05 18:01:18 +03:00
Vladimir Homutov
08691ef3d4 Fixed format specifiers. 2020-03-05 17:51:22 +03:00
Vladimir Homutov
fe30a167d2 Style. 2020-03-05 17:24:04 +03:00
Vladimir Homutov
32b2728ebb Added functions to decrypt long packets. 2020-03-05 17:18:33 +03:00
Sergey Kandaurov
12fc8a8bac Fixed ngx_quic_varint_len misuse in the previous change. 2020-03-05 15:26:15 +03:00
Vladimir Homutov
e3e5e21ed5 Macro for calculating size of varint. 2020-03-04 23:24:51 +03:00
Sergey Kandaurov
941d4f1c2e Fixed packet "input" debug log message. 2020-03-05 13:10:01 +03:00
Sergey Kandaurov
0bc9857b47 Using SSL cipher suite id to obtain cipher/digest, part 1.
While here, log the negotiated cipher just once, - after handshake.
2020-03-05 13:00:59 +03:00
Sergey Kandaurov
46bd853801 Using cached ssl_conn in ngx_quic_handshake_input(), NFC. 2020-03-05 12:51:49 +03:00
Sergey Kandaurov
9fa29e4043 Adjusted transport parameters stub for active_connection_id_limit.
As was objserved with ngtcp2 client, Finished CRYPTO frame within Handshake
packet may not be sent for some reason if there's nothing to append on 1-RTT.
This results in unnecessary retransmit.  To avoid this edge case, a non-zero
active_connection_id_limit transport parameter is now used to append datagram
with NEW_CONNECTION_ID 1-RTT frames.
2020-03-04 16:05:39 +03:00
Vladimir Homutov
309cdf496d Implemented improved version of quic_output().
Now handshake generates frames, and they are queued in c->quic->frames.
The ngx_quic_output() is called from ngx_quic_flush_flight() or manually,
processes the queue and encrypts all frames according to required encryption
level.
2020-03-04 15:52:12 +03:00
Sergey Kandaurov
3c17072122 QUIC handshake final bits.
Added handling of client Finished, both feeding and acknowledgement.
This includes sending NST in 1-RTT triggered by a handshake process.
2020-03-03 17:25:02 +03:00
Vladimir Homutov
d2deb6d6b4 Split frame and packet generation into separate steps.
While there, a number of QUIC constants from spec defined and magic numbers
were replaced.
2020-03-03 13:30:30 +03:00
Vladimir Homutov
820be1b846 Aded the "ngx_quic_hexdump" macro.
ngx_quic_hexdump0(log, format, buffer, buffer_size);
    - logs hexdump of buffer to specified error log

    ngx_quic_hexdump0(c->log, "this is foo:", foo.data, foo.len);

ngx_quic_hexdump(log, format, buffer, buffer_size, ...)
    - same as hexdump0, but more format/args possible:

    ngx_quic_hexdump(c->log, "a=%d b=%d, foo is:", foo.data, foo.len, a, b);
2020-03-02 21:38:03 +03:00
Roman Arutyunyan
76ac67b36f Simplified subrequest finalization.
Now it looks similar to what it was before background subrequests were
introduced in 9552758a786e.
2020-02-28 19:54:13 +03:00
Dmitry Volyntsev
3733c6fd70 Fixed premature background subrequest finalization.
When "aio" or "aio threads" is used while processing the response body of an
in-memory background subrequest, the subrequest could be finalized with an aio
operation still in progress.  Upon aio completion either parent request is
woken or the old r->write_event_handler is called again.  The latter may result
in request errors.  In either case post_subrequest handler is never called with
the full response body, which is typically expected when using in-memory
subrequests.

Currently in nginx background subrequests are created by the upstream module
and the mirror module.  The issue does not manifest itself with these
subrequests because they are header-only.  But it can manifest itself with
third-party modules which create in-memory background subrequests.
2020-03-02 20:07:36 +03:00
Maxim Dounin
6ba18bc35e Added default overwrite in error_page 494.
We used to have default error_page overwrite for 495, 496, and 497, so
a configuration like

    error_page 495 /error;

will result in error 400, much like without any error_page configured.

The 494 status code was introduced later (in 3848:de59ad6bf557, nginx 0.9.4),
and relevant changes to ngx_http_core_error_page() were missed, resulting
in inconsistent behaviour of "error_page 494" - with error_page configured
it results in 494 being returned instead of 400.

Reported by Frank Liu,
http://mailman.nginx.org/pipermail/nginx/2020-February/058957.html.
2020-02-28 17:21:18 +03:00
Vladimir Homutov
b20ed8f7f1 Moved all QUIC code into ngx_event_quic.c
Introduced ngx_quic_input() and ngx_quic_output() as interface between
nginx and protocol.  They are the only functions that are exported.

While there, added copyrights.
2020-02-28 16:23:25 +03:00
Sergey Kandaurov
8993721298 Introduced quic_version macro, uint16/uint32 routines ported. 2020-02-28 13:09:52 +03:00
Sergey Kandaurov
ef8b06b186 Cleanup. 2020-02-28 13:09:52 +03:00
Vladimir Homutov
eb464a7feb Generic function for HKDF expansion. 2020-02-26 16:56:47 +03:00
Sergey Kandaurov
a3620d469f QUIC header protection routines, introduced ngx_quic_tls_hp(). 2020-02-28 13:09:52 +03:00
Sergey Kandaurov
56eead6176 AEAD routines, introduced ngx_quic_tls_open()/ngx_quic_tls_seal(). 2020-02-28 13:09:52 +03:00
Sergey Kandaurov
8c90e6f440 Transport parameters stub, to complete handshake. 2020-02-28 13:09:52 +03:00
Sergey Kandaurov
27e5e87784 Introduced ngx_quic_secret_t. 2020-02-28 13:09:52 +03:00
Sergey Kandaurov
aba1768d94 QUIC handshake handler, draft 24 bump. 2020-02-28 13:09:52 +03:00
Sergey Kandaurov
56a80c228a Fixed indentation. 2020-02-28 13:09:52 +03:00
Sergey Kandaurov
0ddf4a2e67 PN-aware AEAD nonce, feeding proper CRYPTO length. 2020-02-28 13:09:52 +03:00
Sergey Kandaurov
ac640641a6 OpenSSL compatibility. 2020-02-28 13:09:51 +03:00
Sergey Kandaurov
812a0b69a0 QUIC add_handshake_data callback, varint routines. 2020-02-28 13:09:51 +03:00
Sergey Kandaurov
b77c2d00b5 QUIC set_encryption_secrets callback. 2020-02-28 13:09:51 +03:00
Sergey Kandaurov
f03fe91663 Server Initial Keys. 2020-02-28 13:09:51 +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
ba27037a49 Mp4: fixed possible chunk offset overflow.
In "co64" atom chunk start offset is a 64-bit unsigned integer.  When trimming
the "mdat" atom, chunk offsets are casted to off_t values which are typically
64-bit signed integers.  A specially crafted mp4 file with huge chunk offsets
may lead to off_t overflow and result in negative trim boundaries.

The consequences of the overflow are:
- Incorrect Content-Length header value in the response.
- Negative left boundary of the response file buffer holding the trimmed "mdat".
  This leads to pread()/sendfile() errors followed by closing the client
  connection.

On rare systems where off_t is a 32-bit integer, this scenario is also feasible
with the "stco" atom.

The fix is to add checks which make sure data chunks referenced by each track
are within the mp4 file boundaries.  Additionally a few more checks are added to
ensure mp4 file consistency and log errors.
2020-02-26 15:10:46 +03:00
Sergey Kandaurov
f909a7dc33 Disabled connection reuse while in SSL handshake.
During SSL handshake, the connection could be reused in the OCSP stapling
callback, if configured, which subsequently leads to a segmentation fault.
2020-02-27 19:03:21 +03:00
Maxim Dounin
37984f0be1 Disabled duplicate "Host" headers (ticket #1724).
Duplicate "Host" headers were allowed in nginx 0.7.0 (revision b9de93d804ea)
as a workaround for some broken Motorola phones which used to generate
requests with two "Host" headers[1].  It is believed that this workaround
is no longer relevant.

[1] http://mailman.nginx.org/pipermail/nginx-ru/2008-May/017845.html
2020-02-20 16:51:07 +03:00
Maxim Dounin
b4d6b70d7f Removed "Transfer-Encoding: identity" support.
The "identity" transfer coding has been removed in RFC 7230.  It is
believed that it is not used in real life, and at the same time it
provides a potential attack vector.
2020-02-20 16:19:34 +03:00
Maxim Dounin
e64d798edb Disabled multiple Transfer-Encoding headers.
We anyway do not support more than one transfer encoding, so accepting
requests with multiple Transfer-Encoding headers doesn't make sense.
Further, we do not handle multiple headers, and ignore anything but
the first header.

Reported by Filippo Valsorda.
2020-02-20 16:19:29 +03:00
Vladimir Homutov
de5a054b33 Made ngx_http_get_forwarded_addr_internal() non-recursive. 2020-02-11 13:22:44 +03:00
Sergey Kandaurov
16168dcb01 HTTP/2: fixed socket leak with an incomplete HEADERS frame.
A connection could get stuck without timers if a client has partially sent
the HEADERS frame such that it was split on the individual header boundary.
In this case, it cannot be processed without the rest of the HEADERS frame.

The fix is to call ngx_http_v2_state_headers_save() in this case.  Normally,
it would be called from the ngx_http_v2_state_header_block() handler on the
next iteration, when there is not enough data to continue processing.  This
isn't the case if recv_buffer became empty and there's no more data to read.
2020-02-05 16:29:23 +03:00
Sergey Kandaurov
b7ea950a12 Version bump. 2020-02-05 16:29:14 +03:00
Vladimir Homutov
0e3b3b5735 gRPC: variables support in the "grpc_pass" directive. 2020-01-17 12:13:02 +03:00
Daniil Bondarev
60f648f035 HTTP/2: removed ngx_debug_point() call.
With the recent change to prevent frames flood in d4448892a294,
nginx will finalize the connection with NGX_HTTP_V2_INTERNAL_ERROR
whenever flood is detected, causing nginx aborting or stopping if
the debug_points directive is used in nginx config.
2020-01-14 14:20:08 +03:00
Maxim Dounin
fb34316d68 SSL: reworked posted next events again.
Previous change 1ce3f01a4355 incorrectly introduced processing of the
ngx_posted_next_events queue at the end of operation, effectively making
posted next events a nop, since at the end of an event loop iteration
the queue is always empty.  Correct approach is to move events to the
ngx_posted_events queue at an iteration start, as it was done previously.

Further, in some cases the c->read event might be already in the
ngx_posted_events queue, and calling ngx_post_event() with the
ngx_posted_next_events queue won't do anything.  To make sure the event
will be correctly placed into the ngx_posted_next_events queue
we now check if it is already posted.
2019-12-27 19:43:01 +03:00
Maxim Dounin
a8c9ce39d0 Version bump. 2019-12-27 17:20:20 +03:00
Maxim Dounin
24f18aea8c SSL: reworked posted next events.
Introduced in 9d2ad2fb4423 available bytes handling in SSL relied
on connection read handler being overwritten to set the ready flag
and the amount of available bytes.  This approach is, however, does
not work properly when connection read handler is changed, for example,
when switching to a next pipelined request, and can result in unexpected
connection timeouts, see here:

http://mailman.nginx.org/pipermail/nginx-devel/2019-December/012825.html

Fix is to introduce ngx_event_process_posted_next() instead, which
will set ready and available regardless of how event handler is set.
2019-12-24 17:24:59 +03:00
Maxim Dounin
810559665a HTTP/2: introduced separate handler to retry stream close.
When ngx_http_v2_close_stream_handler() is used to retry stream close
after queued frames are sent, client timeouts on the stream can be
logged multiple times and/or in addition to already happened errors.
To resolve this, separate ngx_http_v2_retry_close_stream_handler()
was introduced, which does not try to log timeouts.
2019-12-23 21:25:21 +03:00
Maxim Dounin
49709f75b2 HTTP/2: fixed socket leak with queued frames (ticket #1689).
If a stream is closed with queued frames, it is possible that no further
write events will occur on the stream, leading to the socket leak.
To fix this, the stream's fake connection read handler is set to
ngx_http_v2_close_stream_handler(), to make sure that finalizing the
connection with ngx_http_v2_finalize_connection() will be able to
close the stream regardless of the current number of queued frames.

Additionally, the stream's fake connection fc->error flag is explicitly
set, so ngx_http_v2_handle_stream() will post a write event when queued
frames are finally sent even if stream flow control window is exhausted.
2019-12-23 21:25:17 +03:00
Maxim Dounin
5e5fa2e9e5 Dav: added checks for chunked to body presence conditions.
These checks were missed when chunked support was introduced.  And also
added an explicit error message to ngx_http_dav_copy_move_handler()
(it was missed for some reason, in contrast to DELETE and MKCOL handlers).
2019-12-23 20:39:27 +03:00
Ruslan Ermilov
c1be55f972 Discard request body when redirecting to a URL via error_page.
Reported by Bert JW Regeer and Francisco Oca Gonzalez.
2019-12-23 15:45:46 +03:00
Ruslan Ermilov
4c031f9a6a Rewrite: disallow empty replacements.
While empty replacements were caught at run-time, parsing code
of the "rewrite" directive expects that a minimum length of the
"replacement" argument is 1.
2019-12-16 15:19:01 +03:00
Ruslan Ermilov
a5895eb502 Tolerate '\0' in URI when mapping URI to path.
If a rewritten URI has the null character, only a part of URI was
copied to a memory buffer allocated for path.  In some setups this
could be exploited to expose uninitialized memory via the Location
header.
2019-12-16 15:19:01 +03:00
Ruslan Ermilov
af8ea176a7 Rewrite: fixed segfault with rewritten URI and "alias".
The "alias" directive cannot be used in the same location where URI
was rewritten.  This has been detected in the "rewrite ... break"
case, but not when the standalone "break" directive was used.

This change also fixes proxy_pass with URI component in a similar
case:

       location /aaa/ {
           rewrite ^ /xxx/yyy;
           break;
           proxy_pass http://localhost:8080/bbb/;
       }

Previously, the "/bbb/yyy" would be sent to a backend instead of
"/xxx/yyy".  And if location's prefix was longer than the rewritten
URI, a segmentation fault might occur.
2019-12-16 15:19:01 +03:00
Ruslan Ermilov
48086f79ad Fixed request finalization in ngx_http_index_handler().
Returning 500 instead of NGX_ERROR is preferable here because
header has not yet been sent to the client.
2019-12-16 15:19:01 +03:00
Ruslan Ermilov
be45a3aa59 Saved some memory allocations.
In configurations when "root" has variables, some modules unnecessarily
allocated memory for the "Location" header value.
2019-12-16 15:19:01 +03:00
Ruslan Ermilov
6dc0c880e5 Dav: fixed Location in successful MKCOL response.
Instead of reducing URI length to not include the terminating '\0'
character in 6ddaac3e0bf7, restore the terminating '/' character.
2019-12-16 15:19:01 +03:00
Maxim Dounin
953f539215 Upstream keepalive: clearing of c->data in cached connections.
Previously, connections returned from keepalive cache had c->data
pointing to the keepalive cache item.  While this shouldn't be a problem
for correct code, as c->data is not expected to be used before it is set,
explicitly clearing it might help to avoid confusion.
2019-12-05 19:38:06 +03:00
Maxim Dounin
d77ec5493c Version bump. 2019-12-05 19:22:48 +03:00
Roman Arutyunyan
5dc242e8f7 Limit conn: added shared context.
Previously only an rbtree was associated with a limit_conn.  To make it
possible to associate more data with a limit_conn, shared context is introduced
similar to limit_req.  Also, shared pool pointer is kept in a way similar to
limit_req.
2019-11-18 19:50:59 +03:00
Roman Arutyunyan
3a55d60d2d Limit conn: $limit_conn_status variable.
The variable takes one of the values: PASSED, REJECTED or REJECTED_DRY_RUN.
2019-11-18 17:48:32 +03:00
Roman Arutyunyan
b48c8718bf Limit conn: limit_conn_dry_run directive.
A new directive limit_conn_dry_run allows enabling the dry run mode.  In this
mode connections are not rejected, but reject status is logged as usual.
2019-11-19 11:30:41 +03:00
Roman Arutyunyan
271b12c711 Updated comment after 776d1bebdca2. 2019-11-18 17:46:52 +03:00
Roman Arutyunyan
02ec15dc0d Limit req: $limit_req_status variable.
The variable takes one of the values: PASSED, DELAYED, REJECTED,
DELAYED_DRY_RUN or REJECTED_DRY_RUN.
2019-11-06 19:03:18 +03:00
Roman Arutyunyan
203898505c Parsing server PROXY protocol address and port (ticket #1206).
New variables $proxy_protocol_server_addr and $proxy_protocol_server_port are
added both to HTTP and Stream.
2019-10-21 20:22:30 +03:00
Roman Arutyunyan
be932e81a1 Core: moved PROXY protocol fields out of ngx_connection_t.
Now a new structure ngx_proxy_protocol_t holds these fields.  This allows
to add more PROXY protocol fields in the future without modifying the
connection structure.
2019-10-21 18:06:19 +03:00
Roman Arutyunyan
0098761cb8 Version bump. 2019-10-24 13:47:28 +03:00
Maxim Dounin
2393e25acb Win32: silenced -Wcast-function-type GCC warning (ticket #1865).
With MinGW-w64, building 64-bit nginx binary with GCC 8 and above
results in warning due to cast of GetProcAddress() result to ngx_wsapoll_pt,
which GCC thinks is incorrect.  Added intermediate cast to "void *" to
silence the warning.
2019-10-21 19:07:03 +03:00
Maxim Dounin
9aa906a684 Win32: improved fallback on FormatMessage() errors.
FormatMessage() seems to return many errors which essentially indicate that
the language in question is not available.  At least the following were
observed in the wild and during testing: ERROR_MUI_FILE_NOT_FOUND (15100)
(ticket #1868), ERROR_RESOURCE_TYPE_NOT_FOUND (1813).  While documentation
says it should be ERROR_RESOURCE_LANG_NOT_FOUND (1815), this doesn't seem
to be the case.

As such, checking error code was removed, and as long as FormatMessage()
returns an error, we now always try the default language.
2019-10-21 19:06:12 +03:00
Maxim Dounin
798fcf1ab4 SSL: available bytes handling (ticket #1431).
Added code to track number of bytes available in the socket.
This makes it possible to avoid looping for a long time while
working with fast enough peer when data are added to the socket buffer
faster than we are able to read and process data.

When kernel does not provide number of bytes available, it is
retrieved using ioctl(FIONREAD) as long as a buffer is filled by
SSL_read().

It is assumed that number of bytes returned by SSL_read() is close
to the number of bytes read from the socket, as we do not use
SSL compression.  But even if it is not true for some reason, this
is not important, as we post an additional reading event anyway.

Note that data can be buffered at SSL layer, and it is not possible
to simply stop reading at some point and wait till the event will
be reported by the kernel again.  This can be only done when there
are no data in SSL buffers, and there is no good way to find out if
it's the case.

Instead of trying to figure out if SSL buffers are empty, this patch
introduces events posted for the next event loop iteration - such
events will be processed only on the next event loop iteration,
after going into the kernel and retrieving additional events.  This
seems to be simple and reliable approach.
2019-10-17 16:02:24 +03:00
Maxim Dounin
fac4c7bdf5 Events: available bytes calculation via ioctl(FIONREAD).
This makes it possible to avoid looping for a long time while working
with a fast enough peer when data are added to the socket buffer faster
than we are able to read and process them (ticket #1431).  This is
basically what we already do on FreeBSD with kqueue, where information
about the number of bytes in the socket buffer is returned by
the kevent() call.

With other event methods rev->available is now set to -1 when the socket
is ready for reading.  Later in ngx_recv() and ngx_recv_chain(), if
full buffer is received, real number of bytes in the socket buffer is
retrieved using ioctl(FIONREAD).  Reading more than this number of bytes
ensures that even with edge-triggered event methods the event will be
triggered again, so it is safe to stop processing of the socket and
switch to other connections.

Using ioctl(FIONREAD) only after reading a full buffer is an optimization.
With this approach we only call ioctl(FIONREAD) when there are at least
two recv()/readv() calls.
2019-10-17 16:02:19 +03:00
Maxim Dounin
d2ea226229 SSL: improved ngx_ssl_recv_chain() to stop if c->read->ready is 0.
As long as there are data to read in the socket, yet the amount of data
is less than total size of the buffers in the chain, this saves one
unneeded read() syscall.  Before this change, reading only stopped if
ngx_ssl_recv() returned no data, that is, two read() syscalls in a row
returned EAGAIN.
2019-10-17 16:02:13 +03:00
Maxim Dounin
60609f2372 Event pipe: disabled c->read->available checking for SSL.
In SSL connections, data can be buffered by the SSL layer, and it is
wrong to avoid doing c->recv_chain() if c->read->available is 0 and
c->read->pending_eof is set.  And tests show that the optimization in
question indeed can result in incorrect detection of premature connection
close if upstream closes the connection without sending a close notify
alert at the same time.  Fix is to disable c->read->available optimization
for SSL connections.
2019-10-17 16:02:03 +03:00
Ruslan Ermilov
3c84e4b705 Fixed header parsing with ignore_invalid_headers switched off.
The parsing was broken when the first character of the header name was invalid.

Based on a patch by Alan Kemp.
2019-10-15 14:46:10 +03:00
Maxim Dounin
85137dd2a6 Fixed URI normalization with merge_slashes switched off.
Previously, "/foo///../bar" was normalized into "/foo/bar"
instead of "/foo//bar".
2019-10-08 21:56:14 +03:00
Ruslan Ermilov
ed42131da6 The "/." and "/.." at the end of URI should be normalized. 2019-10-08 21:56:14 +03:00
Ruslan Ermilov
2ac24f1c88 Improved detection of broken percent encoding in URI. 2019-10-08 21:56:14 +03:00
Vladimir Homutov
f7999fe689 Core: removed dead code in ngx_rbtree_delete().
The result of ngx_rbtree_min() is always a node with the left child equal to
sentinel, thus the check is unnecessary.
2019-09-30 16:39:20 +03:00
Vladimir Homutov
201062c83f Version bump. 2019-09-30 16:43:16 +03:00
Ruslan Ermilov
6052881a98 HTTP/2: fixed worker_shutdown_timeout. 2019-09-23 15:45:36 +03:00
Ruslan Ermilov
f878492af3 HTTP/2: fixed possible alert about left open socket on shutdown.
This could happen when graceful shutdown configured by worker_shutdown_timeout
times out and is then followed by another timeout such as proxy_read_timeout.
In this case, the HEADERS frame is added to the output queue, but attempt to
send it fails (due to c->error forcibly set during graceful shutdown timeout).
This triggers request finalization which attempts to close the stream.  But the
stream cannot be closed because there is a frame in the output queue, and the
connection cannot be finalized.  This leaves the connection open without any
timer events leading to alert.

The fix is to post write event when sending output queue fails on c->error.
That will finalize the connection.
2019-09-23 15:45:32 +03:00
Maxim Dounin
af0e284b96 HTTP/2: traffic-based flood detection.
With this patch, all traffic over an HTTP/2 connection is counted in
the h2c->total_bytes field, and payload traffic is counted in
the h2c->payload_bytes field.  As long as total traffic is many times
larger than payload traffic, we consider this to be a flood.
2019-09-18 20:28:12 +03:00
Maxim Dounin
4d4201fafd HTTP/2: switched back to RST_STREAM with NO_ERROR.
In 8df664ebe037, we've switched to maximizing stream window instead
of sending RST_STREAM.  Since then handling of RST_STREAM with NO_ERROR
was fixed at least in Chrome, hence we switch back to using RST_STREAM.

This allows more effective rejecting of large bodies, and also minimizes
non-payload traffic to be accounted in the next patch.
2019-09-18 20:28:09 +03:00
Sergey Kandaurov
555dc61b54 SSL: fixed ssl_verify_client error message. 2019-09-16 19:26:42 +03:00
Sergey Kandaurov
4cd1dd28dd Resolver: fixed possible use-after-free while resolving PTR.
Previously, if a response to the PTR request was cached, and ngx_resolver_dup()
failed to allocate memory for the resulting name, then the original node was
freed but left in expire_queue.  A subsequent address resolving would end up
in a use-after-free memory access of the node either in ngx_resolver_expire()
or ngx_resolver_process_ptr(), when accessing it through expire_queue.

The fix is to leave the resolver node intact.
2019-09-10 15:42:34 +03:00
Ruslan Ermilov
c3f8098712 HTTP/2: close connection on zero WINDOW_UPDATE.
Don't waste server resources by sending RST_STREAM frames.  Instead,
reject WINDOW_UPDATE frames with invalid zero increment by closing
connection with PROTOCOL_ERROR.
2019-09-10 15:33:38 +03:00
Ruslan Ermilov
456e213904 HTTP/2: close connection on frames with self-dependency.
Don't waste server resources by sending RST_STREAM frames.  Instead,
reject HEADERS and PRIORITY frames with self-dependency by closing
connection with PROTOCOL_ERROR.
2019-09-10 15:33:37 +03:00
Sergey Kandaurov
5a2ce3f4ee Fixed "return" with discarding invalid chunked body.
When ngx_http_discard_request_body() call was added to ngx_http_send_response(),
there were no return codes other than NGX_OK and NGX_HTTP_INTERNAL_SERVER_ERROR.
Now it can also return NGX_HTTP_BAD_REQUEST, but ngx_http_send_response() still
incorrectly transforms it to NGX_HTTP_INTERNAL_SERVER_ERROR.

The fix is to propagate ngx_http_discard_request_body() errors.
2019-09-04 13:33:51 +03:00
Sergey Kandaurov
77c01f10a1 Detect runaway chunks in ngx_http_parse_chunked().
As defined in HTTP/1.1, body chunks have the following ABNF:

   chunk = chunk-size [ chunk-ext ] CRLF chunk-data CRLF

where chunk-data is a sequence of chunk-size octets.

With this change, chunk-data that doesn't end up with CRLF at chunk-size
offset will be treated as invalid, such as in the example provided below:

4
SEE-THIS-AND-
4
THAT
0
2019-09-03 17:26:56 +03:00
Sergey Kandaurov
9cb22efa3f HTTP/2: discard remaining request body after redirect.
Previously, if unbuffered request body reading wasn't finished before
the request was redirected to a different location using error_page
or X-Accel-Redirect, and the request body is read again, this could
lead to disastrous effects, such as a duplicate post_handler call or
"http request count is zero" alert followed by a segmentation fault.

This happened in the following configuration (ticket #1819):

    location / {
        proxy_request_buffering off;
        proxy_pass http://bad;
        proxy_intercept_errors on;
        error_page 502 = /error;
    }

    location /error {
        proxy_pass http://backend;
    }
2019-08-19 15:16:06 +03:00
Maxim Dounin
1f960ed92a SSL: lowered log level for WSAECONNABORTED errors on Windows.
Winsock uses ECONNABORTED instead of ECONNRESET in some cases.
For non-SSL connections this is already handled since baad3036086e.

Reported at
http://mailman.nginx.org/pipermail/nginx-ru/2019-August/062363.html.
2019-08-16 18:16:21 +03:00
Maxim Dounin
e77ec60db1 Version bump. 2019-08-16 18:16:14 +03:00
Ruslan Ermilov
5ae7269126 HTTP/2: limited number of PRIORITY frames.
Fixed excessive CPU usage caused by a peer that continuously shuffles
priority of streams.  Fix is to limit the number of PRIORITY frames.
2019-08-13 15:43:40 +03:00
Ruslan Ermilov
a987f81dd1 HTTP/2: limited number of DATA frames.
Fixed excessive memory growth and CPU usage if stream windows are
manipulated in a way that results in generating many small DATA frames.
Fix is to limit the number of simultaneously allocated DATA frames.
2019-08-13 15:43:36 +03:00
Sergey Kandaurov
6dfbc8b1c2 HTTP/2: reject zero length headers with PROTOCOL_ERROR.
Fixed uncontrolled memory growth if peer sends a stream of
headers with a 0-length header name and 0-length header value.
Fix is to reject headers with zero name length.
2019-08-13 15:43:32 +03:00
Maxim Dounin
abe660636c Mail: fixed duplicate resolving.
When using SMTP with SSL and resolver, read events might be enabled
during address resolving, leading to duplicate ngx_mail_ssl_handshake_handler()
calls if something arrives from the client, and duplicate session
initialization - including starting another resolving.  This can lead
to a segmentation fault if the session is closed after first resolving
finished.  Fix is to block read events while resolving.

Reported by Robert Norris,
http://mailman.nginx.org/pipermail/nginx/2019-July/058204.html.
2019-08-01 13:50:07 +03:00
Maxim Dounin
39c40428f9 Gzip: fixed "zero size buf" alerts after ac5a741d39cf.
After ac5a741d39cf it is now possible that after zstream.avail_out
reaches 0 and we allocate additional buffer, there will be no more data
to put into this buffer, triggering "zero size buf" alert.  Fix is to
reset b->temporary flag in this case.

Additionally, an optimization added to avoid allocating additional buffer
in this case, by checking if last deflate() call returned Z_STREAM_END.
Note that checking for Z_STREAM_END by itself is not enough to fix alerts,
as deflate() can return Z_STREAM_END without producing any output if the
buffer is smaller than gzip trailer.

Reported by Witold Filipczyk,
http://mailman.nginx.org/pipermail/nginx-devel/2019-July/012469.html.
2019-07-31 17:29:00 +03:00
Maxim Dounin
6179b98ed5 Version bump. 2019-07-31 17:28:41 +03:00
Maxim Dounin
c3fd5f7e76 Core: fixed memory leak on error, missed in c3f60d618c17.
Found by Coverity (CID 1451664).
2019-07-19 17:50:00 +03:00
Maxim Dounin
2187586207 Xslt: fixed potential buffer overflow with null character.
Due to shortcomings of the ccv->zero flag implementation in complex value
interface, length of the resulting string from ngx_http_complex_value()
might either not include terminating null character or include it,
so the only safe way to work with the result is to use it as a
null-terminated string.

Reported by Patrick Wollgast.
2019-07-18 18:27:54 +03:00
Maxim Dounin
ad42d70fed SSI: avoid potential buffer overflow.
When "-" follows a parameter of maximum length, a single byte buffer
overflow happens, since the error branch does not check parameter length.
Fix is to avoid saving "-" to the parameter key, and instead use an error
message with "-" explicitly written.  The message is mostly identical to
one used in similar cases in the preequal state.

Reported by Patrick Wollgast.
2019-07-18 18:27:53 +03:00
Maxim Dounin
20c8c4fe35 Upstream: fixed EOF handling in unbuffered and upgraded modes.
With level-triggered event methods it is important to specify
the NGX_CLOSE_EVENT flag to ngx_handle_read_event(), otherwise
the event won't be removed, resulting in CPU hog.

Reported by Patrick Wollgast.
2019-07-18 18:27:52 +03:00
Maxim Dounin
36dfa020f2 HTTP/2: return error on output on closed stream.
Without this, an (incorrect) output on a closed stream could result in
a socket leak.
2019-07-18 18:27:50 +03:00
Maxim Dounin
551640703a Core: fixed segfault with too large bucket sizes (ticket #1806).
To save memory hash code uses u_short to store resulting bucket sizes,
so maximum bucket size is limited to 65536 minus ngx_cacheline_size (larger
values will be aligned to 65536 which will overflow u_short).  However,
there were no checks to enforce this, and using larger bucket sizes
resulted in overflows and segmentation faults.

Appropriate safety checks to enforce this added to ngx_hash_init().
2019-07-18 18:27:44 +03:00
Maxim Dounin
676d1a0e94 Perl: removed unused variable, forgotten in 975d7ab37b39. 2019-07-17 17:00:57 +03:00
Ilya Leoshkevich
cfa1316368 Gzip: use zlib to write header and trailer.
When nginx is used with zlib patched with [1], which provides
integration with the future IBM Z hardware deflate acceleration, it ends
up computing CRC32 twice: one time in hardware, which always does this,
and one time in software by explicitly calling crc32().

crc32() calls were added in changesets 133:b27548f540ad ("nginx-0.0.1-
2003-09-24-23:51:12 import") and 134:d57c6835225c ("nginx-0.0.1-
2003-09-26-09:45:21 import") as part of gzip wrapping feature - back
then zlib did not support it.

However, since then gzip wrapping was implemented in zlib v1.2.0.4,
and it's already being used by nginx for log compression.

This patch replaces hand-written gzip wrapping with the one provided by
zlib. It simplifies the code, and makes it avoid computing CRC32 twice
when using hardware acceleration.

[1] https://github.com/madler/zlib/pull/410
2019-07-12 12:43:08 +02:00
Maxim Dounin
29fea7d9ec Perl: named locations in $r->internal_redirect(). 2019-07-12 15:39:28 +03:00
Maxim Dounin
8df08b02b8 Perl: expect escaped URIs in $r->internal_redirect().
Similarly to the change in 5491:74bfa803a5aa (1.5.9), we should accept
properly escaped URIs and unescape them as needed, else it is not possible
to handle URIs with question marks.
2019-07-12 15:39:26 +03:00
Maxim Dounin
9e883a2e48 Perl: additional ctx->header_sent checks.
As we now have ctx->header_sent flag, it is further used to prevent
duplicate $r->send_http_header() calls, prevent output before sending
header, and $r->internal_redirect() after sending header.

Further, $r->send_http_header() protected from calls after
$r->internal_redirect().
2019-07-12 15:39:25 +03:00
Maxim Dounin
78b39bd631 Perl: avoid returning 500 if header was already sent.
Returning NGX_HTTP_INTERNAL_SERVER_ERROR if a perl code died after
sending header will lead to a "header already sent" alert.  To avoid
it, we now check if header was already sent, and return NGX_ERROR
instead if it was.
2019-07-12 15:39:25 +03:00
Maxim Dounin
12d6b3b4a1 Perl: avoid redirects on errors.
Previously, redirects scheduled with $r->internal_redirect() were followed
even if the code then died.  Now these are ignored and nginx will return
an error instead.
2019-07-12 15:38:27 +03:00
Maxim Dounin
cae2e68908 Perl: disabled unrelated calls from variable handlers.
Variable handlers are not expected to send anything to the client, cannot
sleep or read body, and are not expected to modify the request.  Added
appropriate protection to prevent accidental foot shooting.
2019-07-12 15:35:31 +03:00
Maxim Dounin
1988783169 Perl: protection against duplicate $r->sleep() calls.
Duplicate $r->sleep() and/or $r->has_request_body() calls result
in undefined behaviour (in practice, connection leaks were observed).
To prevent this, croak() added in appropriate places.
2019-07-12 15:34:37 +03:00
Maxim Dounin
9d266efbc0 Perl: handling of allocation errors.
Previously, allocation errors in nginx.xs were more or less ignored,
potentially resulting in incorrect code execution in specific low-memory
conditions.  This is changed to use ctx->error bit and croak(), similarly
to how output errors are now handled.

Note that this is mostly a cosmetic change, as Perl itself exits on memory
allocation errors, and hence nginx with Perl is hardly usable in low-memory
conditions.
2019-07-12 13:56:23 +03:00
Maxim Dounin
4a0771f9a6 Perl: propagate errors.
When an error happens, the ctx->error bit is now set, and croak()
is called to terminate further processing.  The ctx->error bit is
checked in ngx_http_perl_call_handler() to cancel further processing,
and is also checked in various output functions - to make sure these won't
be called if croak() was handled by an eval{} in perl code.

In particular, this ensures that output chain won't be called after
errors, as filters might not expect this to happen.  This fixes some
segmentation faults under low memory conditions.  Also this stops
request processing after filter finalization or request body reading
errors.

For cases where an HTTP error status can be additionally returned (for
example, 416 (Requested Range Not Satisfiable) from the range filter),
the ctx->status field is also added.
2019-07-12 13:56:21 +03:00
Maxim Dounin
eae5e4dd01 Perl: reworked perl module to pass ctx instead of request.
This ensures that correct ctx is always available, including after
filter finalization.  In particular, this fixes a segmentation fault
with the following configuration:

    location / {
        image_filter test;

        perl 'sub {
            my $r = shift;
            $r->send_http_header();
            $r->print("foo\n");
            $r->print("bar\n");
        }';
    }

This also seems to be the only way to correctly handle filter finalization
in various complex cases, for example, when embedded perl is used both
in the original handler and in an error page called after filter
finalization.
2019-07-12 11:29:22 +03:00
Maxim Dounin
60e7480533 Perl: removed unneeded NGX_DONE test.
The NGX_DONE test in ngx_http_perl_handle_request() was introduced
in 1702:86bb52e28ce0, which also modified ngx_http_perl_call_handler()
to return NGX_DONE with c->destroyed.  The latter part was then
removed in 3050:f54b02dbb12b, so NGX_DONE test is no longer needed.
2019-07-11 23:20:08 +03:00
Maxim Dounin
66e95b50e7 Version bump. 2019-07-09 16:01:32 +03:00
Maxim Dounin
d9887ee2ae Perl: disabled not_modified filter (ticket #1786).
Embedded perl does not set any request fields needed for conditional
requests processing.  Further, filter finalization in the not_modified
filter can cause segmentation faults due to cleared ctx as in
ticket #1786.

Before 5fb1e57c758a (1.7.3) the not_modified filter was implicitly disabled
for perl responses, as r->headers_out.last_modified_time was -1.  This
change restores this behaviour by using the explicit r->disable_not_modified
flag.

Note that this patch doesn't try to address perl module robustness against
filter finalization and other errors returned from filter chains.  It should
be eventually reworked to handle errors instead of ignoring them.
2019-06-17 19:48:56 +03:00
Roman Arutyunyan
dda58fc63b Limit req: limit_req_dry_run directive.
A new directive limit_req_dry_run allows enabling the dry run mode.  In this
mode requests are neither rejected nor delayed, but reject/delay status is
logged as usual.
2019-06-05 19:55:27 +03:00
Roman Arutyunyan
16ebfa999b Upstream: background cache update before cache send (ticket #1782).
In case of filter finalization, essential request fields like r->uri,
r->args etc could be changed, which affected the cache update subrequest.
Also, after filter finalization r->cache could be set to NULL, leading to
null pointer dereference in ngx_http_upstream_cache_background_update().
The fix is to create background cache update subrequest before sending the
cached response.

Since initial introduction in 1aeaae6e9446 (1.11.10) background cache update
subrequest was created after sending the cached response because otherwise it
blocked the parent request output.  In 9552758a786e (1.13.1) background
subrequests were introduced to eliminate the delay before sending the final
part of the cached response.  This also made it possible to create the
background cache update subrequest before sending the response.

Note that creating the subrequest earlier does not change the fact that in case
of filter finalization the background cache update subrequest will likely not
have enough time to successfully update the cache entry.  Filter finalization
leads to the main request termination as soon the current iteration of request
processing is complete.
2019-06-03 20:33:26 +03:00
Niklas Keller
c18658e9fe Upstream hash: fall back to round-robin if hash key is empty. 2019-05-23 16:49:22 +03:00
Roman Arutyunyan
e0768d199d Version bump. 2019-05-27 19:47:50 +03:00
Sergey Kandaurov
ed0b19cdd4 Cache: reset c->body_start when reading a variant on Vary mismatch.
Previously, a variant not present in shared memory and stored on disk using a
secondary key was read using c->body_start from a variant stored with a main
key.  This could result in critical errors "cache file .. has too long header".
2017-08-04 19:37:37 +03:00
Sergey Kandaurov
b1274232db HTTP/2: rejecting invalid stream identifiers with PROTOCOL_ERROR.
Prodded by Xu Yang.
2020-09-02 23:13:36 +03:00
Roman Arutyunyan
554916301c Cache: ignore stale-if-error for 4xx and 5xx codes.
Previously the stale-if-error extension of the Cache-Control upstream header
triggered the return of a stale response for all error conditions that can be
specified in the proxy_cache_use_stale directive.  The list of these errors
includes both network/timeout/format errors, as well as some HTTP codes like
503, 504, 403, 429 etc.  The latter prevented a cache entry from being updated
by a response with any of these HTTP codes during the stale-if-error period.

Now stale-if-error only works for network/timeout/format errors and ignores
the upstream HTTP code.  The return of a stale response for certain HTTP codes
is still possible using the proxy_cache_use_stale directive.

This change also applies to the stale-while-revalidate extension of the
Cache-Control header, which triggers stale-if-error if it is missing.

Reported at
http://mailman.nginx.org/pipermail/nginx/2020-July/059723.html.
2020-07-29 13:28:04 +03:00
Roman Arutyunyan
d961012799 Version bump. 2020-08-14 12:45:52 +03:00
Sergey Kandaurov
c17bc31d41 SSL: removed OpenSSL 0.9.7 compatibility. 2016-04-11 15:46:36 +03:00
Maxim Dounin
2015a54821 Range filter: fixed duplicate last buffers.
In ngx_http_range_singlepart_body() special buffers where passed
unmodified, including ones after the end of the range.  As such,
if the last buffer of a response was sent separately as a special
buffer, two buffers with b->last_buf set were present in the response.

In particular, this might result in a duplicate final chunk when using
chunked transfer encoding (normally range filter and chunked transfer
encoding are not used together, but this may happen if there are trailers
in the response).  This also likely to cause problems in HTTP/2.

Fix is to skip all special buffers after we've sent the last part of
the range requested.  These special buffers are not meaningful anyway,
since we set b->last_buf in the buffer with the last part of the range,
and everything is expected to be flushed due to it.

Additionally, ngx_http_next_body_filter() is now called even
if no buffers are to be passed to it.  This ensures that various
write events are properly propagated through the filter chain.  In
particular, this fixes test failures observed with the above change
and aio enabled.
2019-05-13 22:44:49 +03:00
Maxim Dounin
ce0f35317e Range filter: fixed loss of incoming chain links.
Filters are not allowed to change incoming chain links, and should allocate
their own links if any modifications are needed.  Nevertheless
ngx_http_range_singlepart_body() modified incoming chain links in some
cases, notably at the end of the requested range.

No problems caused by this are currently known, mostly because of
limited number of possible modifications and the position of the range
body filter in the filter chain.  Though this behaviour is clearly incorrect
and tests demonstrate that it can at least cause some proxy buffers being
lost when using proxy_force_ranges, leading to less effective handling
of responses.

Fix is to always allocate new chain links in ngx_http_range_singlepart_body().
Links are explicitly freed to ensure constant memory usage with long-lived
requests.
2019-05-13 22:44:02 +03:00
Ruslan Ermilov
27b3d3dcca Variables support in proxy_upload_rate and proxy_download_rate. 2019-04-24 16:38:56 +03:00
Ruslan Ermilov
0e2653877e Variables support in limit_rate and limit_rate_after (ticket #293). 2019-04-24 16:38:54 +03:00
Ruslan Ermilov
2ace7fc3e6 Added ngx_http_set_complex_value_size_slot().
If a complex value is expected to be of type size_t, and the compiled
value is constant, the constant size_t value is remembered at compile
time.

The value is accessed through ngx_http_complex_value_size() which
either returns the remembered constant or evaluates the expression
and parses it as size_t.
2019-04-24 16:38:51 +03:00
Vladimir Homutov
2eb2a93d8a Core: enabled "include" in any context (ticket #1615). 2019-04-09 11:40:20 +03:00
Vladimir Homutov
68b147535a Version bump. 2019-04-24 13:41:29 +03:00
Maxim Dounin
f09eae2a75 Fixed incorrect length handling in ngx_utf8_length().
Previously, ngx_utf8_decode() was called from ngx_utf8_length() with
incorrect length, potentially resulting in out-of-bounds read when
handling invalid UTF-8 strings.

In practice out-of-bounds reads are not possible though, as autoindex, the
only user of ngx_utf8_length(), provides null-terminated strings, and
ngx_utf8_decode() anyway returns an errors when it sees a null in the
middle of an UTF-8 sequence.

Reported by Yunbin Liu.
2019-04-15 20:14:07 +03:00
Maxim Dounin
5784889fb9 OCSP stapling: fixed segfault with dynamic certificate loading.
If OCSP stapling was enabled with dynamic certificate loading, with some
OpenSSL versions (1.0.2o and older, 1.1.0h and older; fixed in 1.0.2p,
1.1.0i, 1.1.1) a segmentation fault might happen.

The reason is that during an abbreviated handshake the certificate
callback is not called, but the certificate status callback was called
(https://github.com/openssl/openssl/issues/1662), leading to NULL being
returned from SSL_get_certificate().

Fix is to explicitly check SSL_get_certificate() result.
2019-04-15 19:13:09 +03:00
Maxim Dounin
aaa1a57060 Version bump. 2019-04-15 19:13:06 +03:00
Sergey Kandaurov
db5c307280 OCSP stapling: open ssl_stapling_file in binary-mode.
OCSP response uses the DER format and as such needs to be opened in binary-mode.
This only has any effect under Win32.
2019-04-03 15:35:39 +03:00
Nikolay Morozov
52d9da8790 SSL: missing free calls in $ssl_client_s_dn and $ssl_client_i_dn.
If X509_get_issuer_name() or X509_get_subject_name() returned NULL,
this could lead to a certificate reference leak.  It cannot happen
in practice though, since each function returns an internal pointer
to a mandatory subfield of the certificate successfully decoded by
d2i_X509() during certificate message processing (closes #1751).
2019-03-26 09:33:57 +03:00
Sergey Kandaurov
1c906828ae Version bump. 2019-03-26 18:25:08 +03:00
Roman Arutyunyan
912fb44e25 Listen port ranges.
A range is specified with a dash.  For each port in a range a separate listen
socket is created.

Examples:

    listen 8080-9000;
    listen example.com:80-88;
2019-03-06 20:46:09 +03:00
Roman Arutyunyan
b92e8ffa13 Removed sorting of getaddrinfo() results.
Previously the ngx_inet_resolve_host() function sorted addresses in a way that
IPv4 addresses came before IPv6 addresses.  This was implemented in eaf95350d75c
(1.3.10) along with the introduction of getaddrinfo() which could resolve host
names to IPv6 addresses.  Since the "listen" directive only used the first
address, sorting allowed to preserve "listen" compatibility with the previous
behavior and with the behavior of nginx built without IPv6 support.  Now
"listen" uses all resolved addresses which makes sorting pointless.
2019-03-20 20:31:59 +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
59c34b6795 SSL: support for parsing PEM certificates from memory.
This makes it possible to provide certificates directly via variables
in ssl_certificate / ssl_certificate_key directives, without using
intermediate files.
2019-03-09 03:03:56 +03:00
Maxim Dounin
762d98abed SSL: removed redundant "pkey" variable.
It was accidentally introduced in 77436d9951a1 (1.15.9).  In MSVC 2015
and more recent MSVC versions it triggers warning C4456 (declaration of
'pkey' hides previous local declaration).  Previously, all such warnings
were resolved in 2a621245f4cf.

Reported by Steve Stevenson.
2019-03-09 02:55:43 +03:00
Maxim Dounin
0ad4393e30 SSL: moved c->ssl->handshaked check in server name callback.
Server name callback is always called by OpenSSL, even
if server_name extension is not present in ClientHello.  As such,
checking c->ssl->handshaked before the SSL_get_servername() result
should help to more effectively prevent renegotiation in
OpenSSL 1.1.0 - 1.1.0g, where neither SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
nor SSL_OP_NO_RENEGOTIATION is available.
2019-03-05 16:34:19 +03:00
Maxim Dounin
0808b04c46 SSL: use of the SSL_OP_NO_CLIENT_RENEGOTIATION option.
The SSL_OP_NO_CLIENT_RENEGOTIATION option was introduced in LibreSSL 2.5.1.
Unlike OpenSSL's SSL_OP_NO_RENEGOTIATION, it only disables client-initiated
renegotiation, and hence can be safely used on all SSL contexts.
2019-03-03 16:49:02 +03:00
Maxim Dounin
fe43346dc3 SSL: fixed potential leak on memory allocation errors.
If ngx_pool_cleanup_add() fails, we have to clean just created SSL context
manually, thus appropriate call added.

Additionally, ngx_pool_cleanup_add() moved closer to ngx_ssl_create() in
the ngx_http_ssl_module, to make sure there are no leaks due to intermediate
code.
2019-03-03 16:48:39 +03:00
Maxim Dounin
99d7bb6909 SSL: server name callback changed to return fatal errors.
Notably this affects various allocation errors, and should generally
improve things if an allocation error actually happens during a callback.

Depending on the OpenSSL version, returning an error can result in
either SSL_R_CALLBACK_FAILED or SSL_R_CLIENTHELLO_TLSEXT error from
SSL_do_handshake(), so both errors were switched to the "info" level.
2019-03-03 16:48:06 +03:00
Maxim Dounin
fd97b2a80f SSL: server name callback changed to return SSL_TLSEXT_ERR_OK.
OpenSSL 1.1.1 does not save server name to the session if server name
callback returns anything but SSL_TLSEXT_ERR_OK, thus breaking
the $ssl_server_name variable in resumed sessions.

Since $ssl_server_name can be used even if we've selected the default
server and there are no other servers, it looks like the only viable
solution is to always return SSL_TLSEXT_ERR_OK regardless of the actual
result.

To fix things in the stream module as well, added a dummy server name
callback which always returns SSL_TLSEXT_ERR_OK.
2019-03-03 16:47:44 +03:00
Maxim Dounin
4e0c46cfe1 Version bump. 2019-03-03 16:47:41 +03:00
Maxim Dounin
1a30d79c42 SSL: fixed possible segfault with dynamic certificates.
A virtual server may have no SSL context if it does not have certificates
defined, so we have to use config of the ngx_http_ssl_module from the
SSL context in the certificate callback.  To do so, it is now passed as
the argument of the callback.

The stream module doesn't really need any changes, but was modified as
well to match http code.
2019-02-25 21:16:26 +03:00
Maxim Dounin
ecfab06cb2 SSL: adjusted session id context with dynamic certificates.
Dynamic certificates re-introduce problem with incorrect session
reuse (AKA "virtual host confusion", CVE-2014-3616), since there are
no server certificates to generate session id context from.

To prevent this, session id context is now generated from ssl_certificate
directives as specified in the configuration.  This approach prevents
incorrect session reuse in most cases, while still allowing sharing
sessions across multiple machines with ssl_session_ticket_key set as
long as configurations are identical.
2019-02-25 16:42:54 +03:00
Maxim Dounin
fbcb0c8a33 SSL: dynamic certificate loading in the stream module. 2019-02-25 16:42:43 +03:00
Maxim Dounin
8772a0e089 SSL: passwords support for dynamic certificate loading.
Passwords have to be copied to the configuration pool to be used
at runtime.  Also, to prevent blocking on stdin (with "daemon off;")
an empty password list is provided.

To make things simpler, password handling was modified to allow
an empty array (with 0 elements and elts set to NULL) as an equivalent
of an array with 1 empty password.
2019-02-25 16:42:23 +03:00
Maxim Dounin
6e5a731edb SSL: variables support in ssl_certificate and ssl_certificate_key.
To evaluate variables, a request is created in the certificate callback,
and then freed.  To do this without side effects on the stub_status
counters and connection state, an additional function was introduced,
ngx_http_alloc_request().

Only works with OpenSSL 1.0.2+, since there is no SSL_CTX_set_cert_cb()
in older versions.
2019-02-25 16:42:05 +03:00
Maxim Dounin
9ff7ba3d00 SSL: loading of connection-specific certificates. 2019-02-25 16:41:44 +03:00
Maxim Dounin
20c8700ae7 SSL: reworked ngx_ssl_certificate().
This makes it possible to reuse certificate loading at runtime,
as introduced in the following patches.

Additionally, this improves error logging, so nginx will now log
human-friendly messages "cannot load certificate" instead of only
referring to sometimes cryptic names of OpenSSL functions.
2019-02-25 16:41:28 +03:00
Maxim Dounin
2d7faa2311 SSL: removed logging of empty "(SSL:)" in ngx_ssl_error().
The "(SSL:)" snippet currently appears in logs when nginx code uses
ngx_ssl_error() to log an error, but OpenSSL's error queue is empty.
This can happen either because the error wasn't in fact from OpenSSL,
or because OpenSSL did not indicate the error in the error queue
for some reason.

In particular, currently "(SSL:)" can be seen in errors at least in
the following cases:

- When SSL_write() fails due to a syscall error,
  "[info] ... SSL_write() failed (SSL:) (32: Broken pipe)...".

- When loading a certificate with no data in it,
  "[emerg] PEM_read_bio_X509_AUX(...) failed (SSL:)".
  This can easily happen due to an additional empty line before
  the end line, so all lines of the certificate are interpreted
  as header lines.

- When trying to configure an unknown curve,
  "[emerg] SSL_CTX_set1_curves_list("foo") failed (SSL:)".

Likely there are other cases as well.

With this change, "(SSL:...)" will be only added to the error message
if there is something in the error queue.  This is expected to make
logs more readable in the above cases.  Additionally, with this change
it is now possible to use ngx_ssl_error() to log errors when some
of the possible errors are not from OpenSSL and not expected to have
anything in the error queue.
2019-02-25 16:41:15 +03:00
Maxim Dounin
dce5823f59 Style. 2019-02-25 16:41:08 +03:00
Maxim Dounin
d8ccef0215 Slab: removed redundant page calculation (ticket #1721). 2019-02-12 21:51:15 +03:00
Chanhun Jeong
c5c034f66d Upstream: fixed logging of required buffer size (ticket #1722). 2019-02-11 13:36:53 +09:00
Sergey Kandaurov
fc66ccce02 SSL: fixed EVP_DigestFinal_ex() error message. 2019-02-07 19:39:35 +03:00
Maxim Dounin
f7d53c4ae4 SSL: separate checks for errors in ngx_ssl_read_password_file().
Checking multiple errors at once is a bad practice, as in general
it is not guaranteed that an object can be used after the error.
In this particular case, checking errors after multiple allocations
can result in excessive errors being logged when there is no memory
available.
2019-01-31 19:36:51 +03:00
Ruslan Ermilov
80f105b054 SSL: explicitly zero out session ticket keys. 2019-01-31 19:28:07 +03:00
Roman Arutyunyan
94fa2bb4cb Modules compatibility: down flag in ngx_peer_connection_t. 2019-01-31 17:25:03 +03:00
Ruslan Ermilov
34a8b4506a Use %s for errors returned from configuration parsing handlers. 2018-12-25 15:26:58 +03:00
Sergey Kandaurov
a05e7555ce Removed --test-build-eventport workaround for old FreeBSD versions. 2019-01-28 14:34:02 +00:00
Sergey Kandaurov
f153bcebb5 Fixed portability issues with union sigval.
AIO support in nginx was originally developed against FreeBSD versions 4-6,
where the sival_ptr field was named as sigval_ptr (seemingly by mistake[1]),
which made nginx use the only name available then.  The standard-complaint
name was restored in 2005 (first appeared in FreeBSD 7.0, 2008), retaining
compatibility with previous versions[2][3].  In DragonFly, similar changes
were committed in 2009[4], with backward compatibility recently removed[5].

The change switches to the standard name, retaining compatibility with old
FreeBSD versions.

[1] https://svnweb.freebsd.org/changeset/base/48621
[2] https://svnweb.freebsd.org/changeset/base/152029
[3] https://svnweb.freebsd.org/changeset/base/174003
[4] https://gitweb.dragonflybsd.org/dragonfly.git/commit/3693401
[5] https://gitweb.dragonflybsd.org/dragonfly.git/commit/7875042
2019-01-28 14:33:31 +00:00
Maxim Dounin
38196b8ba6 Win32: detection of connect() errors in select().
On Windows, connect() errors are only reported via exceptfds descriptor set
from select().  Previously exceptfds was set to NULL, and connect() errors
were not detected at all, so connects to closed ports were waiting till
a timeout occurred.

Since ongoing connect() means that there will be a write event active,
except descriptor set is copied from the write one.  While it is possible
to construct except descriptor set as a concatenation of both read and write
descriptor sets, this looks unneeded.

With this change, connect() errors are properly detected now when using
select().  Note well that it is not possible to detect connect() errors with
WSAPoll() (see https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/).
2019-01-24 22:00:44 +03:00
Maxim Dounin
40b74475d0 Win32: added WSAPoll() support.
WSAPoll() is only available with Windows Vista and newer (and only
available during compilation if _WIN32_WINNT >= 0x0600).  To make
sure the code works with Windows XP, we do not redefine _WIN32_WINNT,
but instead load WSAPoll() dynamically if it is not available during
compilation.

Also, sockets are not guaranteed to be small integers on Windows.
So an index array is used instead of NGX_USE_FD_EVENT to map
events to connections.
2019-01-24 21:51:21 +03:00
Maxim Dounin
3dcad9c5d6 Events: fixed copying of old events in poll init.
Previously, the code incorrectly assumed "ngx_event_t *" elements
instead of "struct pollfd".

This is mostly cosmetic change, as this code is never called now.
2019-01-24 21:50:37 +03:00
Roman Arutyunyan
12645b46e9 Stream: do not split datagrams when limiting proxy rate.
Previously, when using proxy_upload_rate and proxy_download_rate, the buffer
size for reading from a socket could be reduced as a result of rate limiting.
For connection-oriented protocols this behavior is normal since unread data will
normally be read at the next iteration.  But for datagram-oriented protocols
this is not the case, and unread part of the datagram is lost.

Now buffer size is not limited for datagrams.  Rate limiting still works in this
case by delaying the next reading event.
2018-12-27 19:37:34 +03:00
Roman Arutyunyan
36a0713244 Prevented scheduling events on a shared connection.
A shared connection does not own its file descriptor, which means that
ngx_handle_read_event/ngx_handle_write_event calls should do nothing for it.
Currently the c->shared flag is checked in several places in the stream proxy
module prior to calling these functions.  However it was not done everywhere.
Missing checks could lead to calling
ngx_handle_read_event/ngx_handle_write_event on shared connections.

The problem manifested itself when using proxy_upload_rate and resulted in
either duplicate file descriptor error (e.g. with epoll) or incorrect further
udp packet processing (e.g. with kqueue).

The fix is to set and reset the event active flag in a way that prevents
ngx_handle_read_event/ngx_handle_write_event from scheduling socket events.
2019-01-14 20:36:23 +03:00
Vladimir Homutov
b6b39b2fb9 Added the ngx_http_test_required_predicates() function.
In contrast to ngx_http_test_predicates(), it requires all values to be
non-empty and not equal to "0".
2019-01-17 14:31:04 +03:00
Vladimir Homutov
de20d73ec5 Version bump. 2019-01-17 14:31:01 +03:00
Vladimir Homutov
910f330ad0 Autoindex: fixed possible integer overflow on 32-bit systems. 2018-12-25 12:59:24 +03:00
Maxim Dounin
aa741f8727 Win32: removed NGX_DIR_MASK concept.
Previous interface of ngx_open_dir() assumed that passed directory name
has a room for NGX_DIR_MASK at the end (NGX_DIR_MASK_LEN bytes).  While all
direct users of ngx_dir_open() followed this interface, this also implied
similar requirements for indirect uses - in particular, via ngx_walk_tree().

Currently none of ngx_walk_tree() uses provides appropriate space, and
fixing this does not look like a right way to go.  Instead, ngx_dir_open()
interface was changed to not require any additional space and use
appropriate allocations instead.
2018-12-24 21:07:05 +03:00
Sergey Kandaurov
499bb2655e Userid: using stub for AF_UNIX addresses.
Previously, AF_UNIX addresses misbehaved as AF_INET, which typically resulted
in $uid_set composed from the middle of sun_path.
2018-12-24 19:55:00 +03:00