summaryrefslogtreecommitdiffhomepage
path: root/src/event/quic/ngx_event_quic_streams.c (follow)
AgeCommit message (Collapse)AuthorFilesLines
2025-05-23QUIC: ssl_encryption_level_t abstraction layer.Sergey Kandaurov1-8/+8
Encryption level values are decoupled from ssl_encryption_level_t, which is now limited to BoringSSL QUIC callbacks, with mappings provided. Although the values match, this provides a technically safe approach, in particular, to access protection level sized arrays. In preparation for using OpenSSL 3.5 TLS callbacks.
2024-12-27QUIC: fixed accessing a released stream.Roman Arutyunyan1-5/+13
While trying to close a stream in ngx_quic_close_streams() by calling its read event handler, the next stream saved prior to that could be destroyed recursively. This caused a segfault while trying to access the next stream. The way the next stream could be destroyed in HTTP/3 is the following. A request stream read event handler ngx_http_request_handler() could end up calling ngx_http_v3_send_cancel_stream() to report a cancelled request stream in the decoder stream. If sending stream cancellation decoder instruction fails for any reason, and the decoder stream is the next in order after the request stream, the issue is triggered. The fix is to postpone calling read event handlers for all streams being closed to avoid closing a released stream.
2024-02-14QUIC: fixed stream cleanup (ticket #2586).Roman Arutyunyan1-0/+1
Stream connection cleanup handler ngx_quic_stream_cleanup_handler() calls ngx_quic_shutdown_stream() after which it resets the pointer from quic stream to the connection (sc->connection = NULL). Previously if this call failed, sc->connection retained the old value, while the connection was freed by the application code. This resulted later in a second attempt to close the freed connection, which lead to allocator double free error. The fix is to reset the sc->connection pointer in case of error.
2023-09-13QUIC: "handshake_timeout" configuration parameter.Roman Arutyunyan1-0/+4
Previously QUIC did not have such parameter and handshake duration was controlled by HTTP/3. However that required creating and storing HTTP/3 session on first client datagram. Apparently there's no convenient way to store the session object until QUIC handshake is complete. In the followup patches session creation will be postponed to init() callback.
2023-05-22QUIC: fixed post-close use-after-free.Roman Arutyunyan1-5/+13
Previously, ngx_quic_close_connection() could be called in a way that QUIC connection was accessed after the call. In most cases the connection is not closed right away, but close timeout is scheduled. However, it's not always the case. Also, if the close process started earlier for a different reason, calling ngx_quic_close_connection() may actually close the connection. The connection object should not be accessed after that. Now, when possible, return statement is added to eliminate post-close connection object access. In other places ngx_quic_close_connection() is substituted with posting close event. Also, the new way of closing connection in ngx_quic_stream_cleanup_handler() fixes another problem in this function. Previously it passed stream connection instead of QUIC connection to ngx_quic_close_connection(). This could result in incomplete connection shutdown. One consequence of that could be that QUIC streams were freed without shutting down their application contexts. This could result in another use-after-free. Found by Coverity (CID 1530402).
2023-05-11QUIC: keep stream sockaddr and addr_text constant.Roman Arutyunyan1-2/+29
HTTP and Stream variables $remote_addr and $binary_remote_addr rely on constant client address, particularly because they are cacheable. However, QUIC client may migrate to a new address. While there's no perfect way to handle this, the proposed solution is to copy client address to QUIC stream at stream creation. The change also fixes truncated $remote_addr if migration happened while the stream was active. The reason is addr_text string was copied to stream by value.
2023-04-27QUIC: set c->socklen for streams.Roman Arutyunyan1-0/+1
Previously, the value was not set and remained zero. While in nginx code the value of c->sockaddr is accessed without taking c->socklen into account, invalid c->socklen could lead to unexpected results in third-party modules.
2023-04-03QUIC: optimized sending stream response.Roman Arutyunyan1-0/+11
When a stream is created by client, it's often the case that nginx will send immediate response on that stream. An example is HTTP/3 request stream, which in most cases quickly replies with at least HTTP headers. QUIC stream init handlers are called from a posted event. Output QUIC frames are also sent to client from a posted event, called the push event. If the push event is posted before the stream init event, then output produced by stream may trigger sending an extra UDP datagram. To address this, push event is now re-posted when a new stream init event is posted. An example is handling 0-RTT packets. Client typically sends an init packet coalesced with a 0-RTT packet. Previously, nginx replied with a padded CRYPTO datagram, followed by a 1-RTT stream reply datagram. Now CRYPTO and STREAM packets are coalesced in one reply datagram, which saves bandwidth. Other examples include coalescing 1-RTT first stream response, and MAX_STREAMS/STREAM sent in response to ACK/STREAM.
2023-02-13QUIC: fixed indentation.Sergey Kandaurov1-1/+1
2023-01-18QUIC: defer setting the active flag for client stream events.Sergey Kandaurov1-18/+21
Specifically, now it is kept unset until streams are initialized. Notably, this unbreaks OCSP with client certificates after 35e27117b593. Previously, the read event could be posted prematurely via ngx_quic_set_event() e.g., as part of handling a STREAM frame.
2023-01-10QUIC: set stream error flag on reset.Roman Arutyunyan1-2/+12
Now, when RESET_STREAM is sent or received, or when streams are closed, stream connection error flag is set. Previously, only stream state was changed, which resulted in setting the error flag only after calling recv()/send()/send_chain(). However, there are cases when none of these functions is called, but it's still important to know if the stream is being closed. For example, when an HTTP/3 request stream is blocked on insert count, receiving RESET_STREAM should trigger stream closure, which was not the case. The change also fixes ngx_http_upstream_check_broken_connection() and ngx_http_test_reading() with QUIC streams.
2023-01-10QUIC: automatically add and never delete stream events.Roman Arutyunyan1-28/+7
Previously, stream events were added and deleted by ngx_handle_read_event() and ngx_handle_write_event() in a way similar to level-triggered events. However, QUIC stream events are effectively edge-triggered and can stay active all time. Moreover, the events are now active since the moment a stream is created.
2023-01-10HTTP/3: fixed $connection_time.Sergey Kandaurov1-0/+1
Previously, start_time wasn't set for a new stream. The fix is to derive it from the parent connection. Also it's used to simplify tracking keepalive_time.
2022-11-30QUIC: application init() callback.Roman Arutyunyan1-3/+19
It's called after handshake completion or prior to the first early data stream creation. The callback should initialize application-level data before creating streams. HTTP/3 callback implementation sets keepalive timer and sends SETTINGS. Also, this allows to limit max handshake time in ngx_http_v3_init_stream().
2022-09-07QUIC: do not send MAX_STREAMS in shutdown state.Roman Arutyunyan1-8/+9
No more streams are expected from client.
2022-08-22QUIC: defer stream removal until all its data is acked.Roman Arutyunyan1-22/+60
Previously, stream was kept alive until all its data is sent. This resulted in disabling retransmission of final part of stream when QUIC connection was closed right after closing stream connection.
2022-11-29QUIC: reusable mode for main connection.Roman Arutyunyan1-17/+83
The connection is automatically switched to this mode by transport layer when there are no non-cancelable streams. Currently, cancelable streams are HTTP/3 encoder/decoder/control streams.
2022-09-07QUIC: post close event for connection close.Roman Arutyunyan1-2/+2
Previously, close event was used only for close timeout, while read event was used for posting connection close.
2022-11-23QUIC: fixed triggering stream read event (ticket #2409).Roman Arutyunyan1-1/+1
If a client packet carrying a stream data frame is not acked due to packet loss, the stream data is retransmitted later by client. It's also possible that the retransmitted range is bigger than before due to more stream data being available by then. If the original data was read out by the application, there would be no read event triggered by the retransmitted frame, even though it contains new data.
2022-02-14QUIC: trim input chain in ngx_quic_buffer_write().Roman Arutyunyan1-5/+0
This allows to eliminate explicit trimming when handling input STREAM frame. As a result, ngx_quic_trim_chain() is eliminated as well.
2022-02-14QUIC: ngx_quic_buffer_t object.Roman Arutyunyan1-29/+22
The object is used instead of ngx_chain_t pointer for buffer operations like ngx_quic_write_chain() and ngx_quic_read_chain(). These functions are renamed to ngx_quic_write_buffer() and ngx_quic_read_buffer().
2022-02-05QUIC: stream lingering.Roman Arutyunyan1-187/+258
Now ngx_quic_stream_t is decoupled from ngx_connection_t in a way that it can persist after connection is closed by application. During this period, server is expecting stream final size from client for correct flow control. Also, buffered output is sent to client as more flow control credit is granted.
2022-02-09QUIC: fixed resetting stream wev->ready flag.Roman Arutyunyan1-1/+1
Previously, the flag could be reset after send_chain() with a limit, even though there was room for more data. The application then started waiting for a write event notification, which never happened. Now the wev->ready flag is only reset when flow control is exhausted.
2022-02-03QUIC: switch stream to DATA_RECVD state.Roman Arutyunyan1-2/+11
The switch happens when received byte counter reaches stream final size. Previously, this state was skipped. The stream went from SIZE_KNOWN to DATA_READ when all bytes were read by application. The change prevents STOP_SENDING frames from being sent when all data is received from client, but not yet fully read by application.
2022-01-26QUIC: stream event setting function.Roman Arutyunyan1-52/+21
The function ngx_quic_set_event() is now called instead of posting events directly.
2022-01-31QUIC: introduced explicit stream states.Roman Arutyunyan1-71/+88
This allows to eliminate the usage of stream connection event flags for tracking stream state.
2022-01-31QUIC: allowed main QUIC connection for some operations.Roman Arutyunyan1-4/+5
Operations like ngx_quic_open_stream(), ngx_http_quic_get_connection(), ngx_http_v3_finalize_connection(), ngx_http_v3_shutdown_connection() used to receive a QUIC stream connection. Now they can receive the main QUIC connection as well. This is useful when calling them from a stream context.
2022-01-16QUIC: fixed format specifier after 3789f4a56d65.Roman Arutyunyan1-1/+1
2022-01-13QUIC: return written size from ngx_quic_write_chain().Roman Arutyunyan1-14/+5
This allows to escape calculating it before calling the function.
2022-01-13QUIC: fixed handling stream input buffers.Roman Arutyunyan1-1/+1
Previously, ngx_quic_write_chain() treated each input buffer as a memory buffer, which is not always the case. Special buffers were not skipped, which is especially important when hitting the input byte limit. The issue manifested itself with ngx_quic_write_chain() returning a non-empty chain consisting of a special last_buf buffer when called from QUIC stream send_chain(). In order for this to happen, input byte limit should be equal to the chain length, and the input chain should end with an empty last_buf buffer. An easy way to achieve this is the following: location /empty { return 200; } When this non-empty chain was returned from send_chain(), it signalled to the caller that input was blocked, while in fact it wasn't. This prevented HTTP request from finalization, which prevented QUIC from sending STREAM FIN to the client. The QUIC stream was then reset after a timeout. Now special buffers are skipped and send_chain() returns NULL in the case above, which signals to the caller a successful operation. Also, original byte limit is now passed to ngx_quic_write_chain() from send_chain() instead of actual chain length to make sure it's never zero.
2022-01-11QUIC: fixed handling STREAM FIN.Roman Arutyunyan1-1/+1
Previously, when a STREAM FIN frame with no data bytes was received after all prior stream data were already read by the application layer, the frame was ignored and eof was not reported to the application.
2021-12-28QUIC: fixed format specifier after 6ccf3867959a.Roman Arutyunyan1-1/+1
2021-12-16QUIC: renamed buffer-related functions.Roman Arutyunyan1-4/+4
ngx_quic_alloc_buf() -> ngx_quic_alloc_chain(), ngx_quic_free_bufs() -> ngx_quic_free_chain(), ngx_quic_trim_bufs() -> ngx_quic_trim_chain()
2021-12-24QUIC: refactored ngx_quic_order_bufs() and ngx_quic_split_bufs().Roman Arutyunyan1-49/+34
They are replaced with ngx_quic_write_chain() and ngx_quic_read_chain(). These functions represent the API to data buffering. The first function adds data of given size at given offset to the buffer. Now it returns the unwritten part of the chain similar to c->send_chain(). The second function returns data of given size from the beginning of the buffer. Its second argument and return value are swapped compared to ngx_quic_split_bufs() to better match ngx_quic_write_chain(). Added, returned and stored data are regular ngx_chain_t/ngx_buf_t chains. Missing data is marked with b->sync flag. The functions are now used in both send and recv data chains in QUIC streams.
2021-12-24QUIC: avoid excessive buffer allocations in stream output.Roman Arutyunyan1-9/+24
Previously, when a few bytes were send to a QUIC stream by the application, a 4K buffer was allocated for these bytes. Then a STREAM frame was created and that entire buffer was used as data for that frame. The frame with the buffer were in use up until the frame was acked by client. Meanwhile, when more bytes were send to the stream, more buffers were allocated and assigned as data to newer STREAM frames. In this scenario most buffer memory is unused. Now the unused part of the stream output buffer is available for further stream output while earlier parts of the buffer are waiting to be acked. This is achieved by splitting the output buffer.
2021-12-13QUIC: write and full stream shutdown support.Roman Arutyunyan1-56/+79
Full stream shutdown is now called from stream cleanup handler instead of explicitly sending frames.
2021-12-10QUIC: simplified stream initialization.Roman Arutyunyan1-172/+62
After creation, a client stream is added to qc->streams.uninitialized queue. After initialization it's removed from the queue. If a stream is never initialized, it is freed in ngx_quic_close_streams(). Stream initializer is now set as read event handler in stream connection. Previously qc->streams.uninitialized was used only for delayed stream initialization. The change makes it possible not to handle separately the case of a new stream in stream-related frame handlers. It makes these handlers simpler since new streams and existing streams are now handled by the same code.
2021-11-23QUIC: post stream events instead of calling their handlers.Roman Arutyunyan1-3/+3
This potentially reduces the number of handler calls.
2021-12-06QUIC: simplified configuration.Vladimir Homutov1-6/+4
Directives that set transport parameters are removed from the configuration. Corresponding values are derived from the quic configuration or initialized to default. Whenever possible, quic configuration parameters are taken from higher-level protocol settings, i.e. HTTP/3.
2021-11-17QUIC: handle DATA_BLOCKED frame from client.Roman Arutyunyan1-15/+45
Previously the frame was not handled and connection was closed with an error. Now, after receiving this frame, global flow control is updated and new flow control credit is sent to client.
2021-11-17QUIC: update stream flow control credit on STREAM_DATA_BLOCKED.Roman Arutyunyan1-37/+44
Previously, after receiving STREAM_DATA_BLOCKED, current flow control limit was sent to client. Now, if the limit can be updated to the full window size, it is updated and the new value is sent to client, otherwise nothing is sent. The change lets client update flow control credit on demand. Also, it saves traffic by not sending MAX_STREAM_DATA with the same value twice.
2021-11-11QUIC: reject streams which we could not create.Roman Arutyunyan1-4/+71
The reasons why a stream may not be created by server currently include hitting worker_connections limit and memory allocation error. Previously in these cases the entire QUIC connection was closed and all its streams were shut down. Now the new stream is rejected and existing streams continue working. To reject an HTTP/3 request stream, RESET_STREAM and STOP_SENDING with H3_REQUEST_REJECTED error code are sent to client. HTTP/3 uni streams and Stream streams are not rejected.
2021-11-12QUIC: stop processing new client streams at the closing state.Sergey Kandaurov1-2/+2
2021-09-23QUIC: added shutdown support in stream proxy.Vladimir Homutov1-0/+50
2021-10-26QUIC: refactored OCSP validation in preparation for 0-RTT support.Sergey Kandaurov1-1/+31
2021-09-21QUIC: send RESET_STREAM in response to STOP_SENDING.Roman Arutyunyan1-5/+13
As per RFC 9000: An endpoint that receives a STOP_SENDING frame MUST send a RESET_STREAM frame if the stream is in the "Ready" or "Send" state. An endpoint SHOULD copy the error code from the STOP_SENDING frame to the RESET_STREAM frame it sends, but it can use any application error code.
2021-09-22QUIC: reset stream only once.Roman Arutyunyan1-1/+6
2021-09-22QUIC: set NGX_TCP_NODELAY_DISABLED for fake stream connections.Sergey Kandaurov1-0/+1
Notably, it is to avoid setting the TCP_NODELAY flag for QUIC streams in ngx_http_upstream_send_response(). It is an invalid operation on inherently SOCK_DGRAM sockets, which leads to QUIC connection close. The change reduces diff to the default branch in stream content phase.
2021-09-21QUIC: simplified stream fd initialization.Roman Arutyunyan1-2/+1
2021-09-09QUIC: separate event handling functions.Roman Arutyunyan1-0/+28
The functions ngx_quic_handle_read_event() and ngx_quic_handle_write_event() are added. Previously this code was a part of ngx_handle_read_event() and ngx_handle_write_event(). The change simplifies ngx_handle_read_event() and ngx_handle_write_event() by moving QUIC-related code to a QUIC source file.