10.2.0: final batch of For v10.2.0 picks - #13460
Merged
Merged
Conversation
* Add unit tests for SSL Diffie-Hellman key configuration
* Support OpenSSL 3.0 APIs for Diffie-Hellman
* Move DH keygen to SSLKeyUtils.{h,cc}
(cherry picked from commit ec93038)
HTTP/2 origin responses can legally carry a non-zero Content-Length when no payload is sent, such as responses to HEAD requests. ATS discarded the outbound request method after encoding the H2 HEADERS frame and could therefore reject a valid no-body response as a payload-length error. An H2 DATA sender also treated every byte visible through its IOBufferReader as eligible for the current write. Reader availability is independent of the finite VIO operation: VIO::ntodo() is the authoritative boundary, and the ordinary network VConnection already caps writes to it. Without that cap, the regression sent 327,675 bytes for a 300,000-byte PUT and the H2 origin returned GOAWAY with PROTOCOL_ERROR. This retains the outbound request method on the H2 stream for response validation. It also caps DATA payloads to the remaining write VIO bytes, still setting END_STREAM when the final authorized bytes are sent, and extends the H2 origin replay coverage with HEAD and large PUT cases. (cherry picked from commit dcb1850)
The documented -1 value for proxy.config.ssl.max_record_size is incorrectly rejected by records validation, leaving dynamic TLS record sizing unreachable from records.yaml. This widens the accepted range to include the dynamic sentinel, clarifies the documented modes, and extends TLS wire-level coverage to verify the small-to-large record transition. Fixes: apache#13288 (cherry picked from commit a0ece04)
Fedora CI could silently omit the OTEL and WAMR plugins, while BoringSSL builds mixed system OpenSSL headers and libraries. This made the updated dependency image appear usable without proving either plugin could load. This makes the Fedora presets require both plugins and selects the matching curl and TLS roots for system OpenSSL and BoringSSL builds. This also distinguishes BoringSSL from OpenSSL 3 during configuration and gives the WASM targets explicit OpenSSL dependencies so both TLS variants build and load consistently. (cherry picked from commit fa297c3)
The run-plugin action's plugin-argument is parsed once when the
rule loads, like a remap.config argument, and is never
re-evaluated per request, so variable interpolation (e.g.
%{HEADER:bar}) does not work there.
(cherry picked from commit 9a847a5)
Prometheus consumers currently only get flat ATS stat names, which makes related counters hard to aggregate and can hide broken output behind parser leniency. The draft v2 output also exposed that risk by letting `completed` look like a request method and by interleaving samples from the same family. This adds a Prometheus v2 response format that groups samples by metric family and derives labels for methods, directions, status codes, cache results, time buckets, and cache volumes. This keeps lifecycle counters such as completed requests as their own metrics while preserving the existing v1 output. This extends the stats_over_http AuTest and Prometheus ingester to validate both the raw v2 exposition and the parser's view of it. This catches split families, missing TYPE metadata, malformed labels, and regressions in the expected labeled samples. (cherry picked from commit 8d35fd2)
This patch extends the HTTP/3 autest coverage, using curl, Go, Python/aioquic, and Proxy Verifier HTTP/3 clients to generate their implementations of H3 traffic. It also adds request and response bodies of various sizes, including "large" 300k bodies to exercise multiple packet, buffer, and flow control ATS HTTP/3 implementations. It also exercises interesting requests and responses, such as HEAD, 204, PUT, DELETE, OPTIONS, range responses over cached objects, and malformed HTTP/3 frame behavior. This patch also includes the various production fixes needed for these tests. Large request and response bodies exposed a UDP receive starvation bug in the UDP read path. On systems using `recvmmsg()` with edge-triggered readiness, ATS could read one full batch of datagrams and then leave the rest queued in the kernel without another readable event to wake the QUIC stack. This changes `UDPNetProcessorInternal::read_multiple_messages_from_net()` in `src/iocore/net/UnixUDPNet.cc` to return whether the kernel supplied a full batch. `udp_read_from_net()` now processes a bounded number of full batches per event, preserving UDP batching for H3 while avoiding both unread UDP bursts and unbounded net-thread monopolization under sustained QUIC load. The stream write path consumed the `QUICStreamVCAdapter` write reader inside `_read()`, before `QUICStream::send_data()` knew whether `quiche_conn_stream_send()` had accepted the bytes. When quiche accepted only a partial write or returned a flow-control error, ATS could lose stream data and report write progress too early. This makes `QUICStream::send_data()` keep a pending `IOBufferBlock`/FIN pair until quiche reports successful consumption, and only then calls the new `QUICStreamAdapter::consume()` hook. The concrete reader accounting lives in `QUICStreamVCAdapter::_consume()`, while `QUICStream::has_data_to_send()`, `QUICStream::on_write()`, and `QUICNetVConnection::on_stream_updated()` make newly writable stream data schedule packet writes again. This also treats completed finite writes with only FIN left as writable stream state, so empty bodies and fully consumed bodies still close the H3 stream cleanly. The large-body tests exposed that `QUICStreamVCAdapter::_read()` could hand more data to the transaction than the read VIO requested. That was usually hidden by small bodies, but larger reads made finite request-body accounting fragile. This clamps cloned input blocks in `QUICStreamVCAdapter::_read()` to the requested and available byte count before filling the read VIO. The adapter now also checks for a missing reader before touching the read buffer, which makes late stream cleanup paths more defensive. The timeout and stream lifetime tests exposed cases where an `HQTransaction` could be deleted while an event handler was still active, or while the QUIC stream adapter still had read/write cleanup to finish. That left later stream-close and timeout paths touching state that had already been torn down. This makes the transaction and stream closed state derive from the active event handlers instead of separate booleans that could drift from the adapter state. `Http3App::on_stream_close()` now calls `HQTransaction::stream_closed()` while holding the transaction mutex, and `HQTransaction::_delete_if_possible()` waits until the transaction is done, the stream is closed or no longer readable, and pending writes have flushed before deleting the transaction. The aioquic edge-case probes found malformed request streams that were correctly rejected at the H3 layer but still left partially constructed transactions attached to the session. Session teardown then either asserted because the transaction list was not empty or touched the H3 session after `Http3Session` had already nulled its network connection. This adds `HQSession::_close_transactions()` and drains any remaining transactions before destroying the H3 session-specific state. It also lets `Http3App::on_stream_close()` attach a cleanup callback to the transaction so the application stream map is erased when the transaction is actually destroyed, rather than when quiche first reports stream closure. The H3 request read path could signal completion before asynchronous QPACK header decode and buffered DATA delivery had finished updating the sink VIO. That showed up around HEAD, 204, and stream-close timing because the HTTP state machine needed a stable view of whether headers were decoded and whether a request body existed. This updates `Http3HeaderVIOAdaptor::_on_qpack_decode_complete()` to add the printed header length to the sink VIO and notify `Http3Transaction::on_header_decode_complete()`, which schedules the appropriate read event. `Http3StreamDataVIOAdaptor::finalize()` now uses a persistent reader, writes buffered DATA into the sink VIO exactly once, and updates `ndone`/`nbytes` consistently before the transaction is signaled. The aioquic client can write raw QUIC stream data, which exposed gaps in ATS's HTTP/3 frame validation. Reserved frames on request streams, DATA-before-HEADERS, client-created push streams, and duplicate control streams did not all reliably close the QUIC connection with an H3 application error. This adds request-stream enforcement through `Http3ProtocolEnforcer` in `Http3Transaction`, recognizes reserved HTTP/3 frame types in `Http3Frame`, and routes connection-level errors through `Http3App::_handle_error()` and `Http3Transaction::_handle_error()` to close the QUIC connection. The transaction signal path now also avoids calling the HTTP state machine through closed transactions or the initial zero-byte write VIO created before the HTTP response handler is installed. The HEAD, 204, and quic-go coverage exposed that ATS's static QPACK table was not the table used by external HTTP/3 implementations. The extra zstd entry and modified `accept-encoding` value in `src/proxy/http3/QPACK.cc` shifted later static indexes, so an externally encoded `:status 204` could decode as a different status. This restores the standard static table entries by using `accept-encoding: gzip, deflate, br` and removing the non-standard `content-encoding: zstd` entry. The new 204 cases in `tests/gold_tests/h3/replays/h3_proxy_verifier.replay.yaml`, `tests/gold_tests/h3/replays/h3_server_for_go_client.replay.yaml`, and `tests/gold_tests/h3/replays/h3_server_for_python_client.replay.yaml` cover this interoperability point with Proxy Verifier, quic-go, and aioquic. (cherry picked from commit 3076c17)
This adds an AuTest to verify the TSHttpAltInfoQualitySet plugin API. The test verifies alternate creation and selection through observable cached responses. Closes: apache#7205 (cherry picked from commit 799c4cc)
Traffic Server already handles these request shapes correctly; this patch adds no product code and changes no behavior. It only adds test coverage so that the currently correct handling cannot regress unnoticed. A proxy that disagrees with its origin about where a request body ends can be desynchronized from that origin. Two common shapes provoke this: pipelining a body-less POST (Content-Length: 0) ahead of a second request, and sending a request with conflicting Content-Length header fields. Traffic Server must keep such request boundaries intact. This extends the pipeline autest with two runs that exercise those shapes. This confirms that Traffic Server delivers the pipelined requests to the origin as two independent requests, so the second request cannot be folded into the first, and that it rejects the ambiguously-framed request rather than forwarding it. (cherry picked from commit 991524a)
Plugin intercepts provide a PluginVC for the server connection, but HttpSM treats it as a UnixNetVConnection. This invalid downcast can trigger libc++ RTTI diagnostics and is undefined behavior. This keeps the connection at its NetVConnection base type, which provides both TLS service lookups needed at that point. Fixes: apache#8105 (cherry picked from commit 43e0b5d)
JSONRPC server shutdown can race with worker thread startup. When the worker starts after stop_thread(), it restores the running flag and polls a closed socket indefinitely. This causes test_jsonrpcserver and process shutdown to hang. This marks the socket server as running before the worker is created, so a concurrent stop cannot be overwritten. It also passes the owning server to the worker instead of relying on the mutable global server pointer. (cherry picked from commit 8b9a007)
Contributor
Author
|
[approve ci] |
Contributor
Author
|
[approve ci rocky] |
Contributor
Author
|
[approve ci rocky] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft — CI verification
Final batch of last-minute adds for 10.2.0: the 10 PRs sitting at
For v10.2.0in theATS v10.2.xproject, cherry-picked with-xin master merge order.None carry the
Incompatiblelabel; none were already present on 10.2.x.Adaptations for 10.2.x
ssl.session_cache.*records block; applied only thevalidation-range change (
[0-16383]→[-1-16383]) that the fix is about._close_transactions()in the HQSessiondtor,
_handle_error()on the read-vio error path, and the SNI test's cert setup).Its new h3 autests used the
ssl_multicert.yamlDisk API, which the 10.2.x autestharness doesn't provide; converted
h3_curlandh3_go_clientto the flatssl_multicert.configform (the other new h3 tests already guard withhasattr).Testing
Local build clean;
ctest162/163 — the single failure is the pre-existing macOS-localtest_jsonrpcserverunix-socket flake, unrelated to these picks.#13461 was added after the first CI run:
test_jsonrpcserverfailed on Fedora with ahang/timeout, and #13461 fixes exactly that shutdown/startup race. It is also a
For v10.2.0item. Note it does NOT resolve the separate macOS-local failure of that test(a
/var/foldersunix-socketENOENT/EPERM), which is why local runs can't validate it —this CI run is the check.
Note this build had QUIC disabled locally, so CI is the real signal for #13213's H3
changes (and for the new h3 autests generally).