Fix mbedTLS is_peer_closed() destroying the first response byte

Mbed TLS has no SSL_peek() equivalent, so is_peer_closed() (called after
every SSL request write) probed liveness with a real 1-byte
mbedtls_ssl_read() and discarded whatever it read. If the response had
already arrived by the time the probe ran — plausible under CI load or
plain OS scheduling — the probe silently ate the first byte of the
status line, corrupting the response and surfacing as a fast
"Failed to read connection" failure.

This was the root cause of the long-standing MbedTLS-only CI flakiness
(ServerTest cases failing intermittently on Ubuntu and macOS), previously
worked around by reducing gtest shard parallelism. Fix: push the probed
byte back into MbedTlsSession and have tls::read()/pending() account for
it, so no data is lost.

Also fix a second, unrelated flake: ProxyTunnelTest.
OriginReturning407InsideTunnelDoesNotLeakProxyDigest used "localhost" for
its client while the test's proxy harness only listens on 127.0.0.1;
under dual-stack resolution this could race with another test's server
on ::1 using the same ephemeral port. Pin the test to 127.0.0.1.

With the root cause fixed, restore the mbedTLS CI jobs (ubuntu,
ubuntu-26.04, macOS) to the default shard count instead of the
previously reduced SHARDS=1/2 mitigation.
This commit is contained in:
yhirose
2026-07-23 22:41:43 -04:00
parent 82b1492c3d
commit 2fa0417754
3 changed files with 50 additions and 23 deletions

View File

@@ -104,10 +104,7 @@ jobs:
LSAN_OPTIONS: suppressions=lsan_suppressions.txt
- name: build and run tests (Mbed TLS)
if: matrix.tls_backend == 'mbedtls'
# Run mbedTLS shards with reduced parallelism — under ASAN+mbedTLS the
# default 4 shards overload CI runners enough that timing-sensitive
# ServerTest cases flake on first-request keep-alive reuse.
run: cd test && make test_split_mbedtls && SHARDS=2 make test_mbedtls_parallel
run: cd test && make test_split_mbedtls && make test_mbedtls_parallel
- name: build and run tests (wolfSSL)
if: matrix.tls_backend == 'wolfssl'
run: cd test && make test_split_wolfssl && make test_wolfssl_parallel
@@ -142,10 +139,7 @@ jobs:
- name: install Mbed TLS
run: sudo apt-get install -y libmbedtls-dev
- name: build and run tests (Mbed TLS)
# Run mbedTLS shards with reduced parallelism — under ASAN+mbedTLS the
# default 4 shards overload CI runners enough that timing-sensitive
# ServerTest cases flake on first-request keep-alive reuse.
run: cd test && make test_split_mbedtls && SHARDS=2 make test_mbedtls_parallel
run: cd test && make test_split_mbedtls && make test_mbedtls_parallel
# BoringSSL is Google's fork of OpenSSL. It has no API stability guarantee
# and is not packaged by distros, so we build it from source. cpp-httplib
@@ -410,10 +404,7 @@ jobs:
LSAN_OPTIONS: suppressions=lsan_suppressions.txt
- name: build and run tests (Mbed TLS)
if: matrix.tls_backend == 'mbedtls'
# macOS runners under ASAN+mbedTLS still flake at SHARDS=2 (rapid
# bind/connect on the fixture's fixed port races on the slower
# macos-latest runner). Serialize fully here; ubuntu stays at 2.
run: cd test && make test_split_mbedtls && SHARDS=1 make test_mbedtls_parallel
run: cd test && make test_split_mbedtls && make test_mbedtls_parallel
- name: build and run tests (wolfSSL)
if: matrix.tls_backend == 'wolfssl'
run: cd test && make test_split_wolfssl && make test_wolfssl_parallel