From 2ea5939672ac2b48cd736bbe32c7b23234e4f16c Mon Sep 17 00:00:00 2001 From: Motomu Utsumi Date: Fri, 25 Apr 2025 14:56:11 +0900 Subject: [PATCH 1/2] Enable QUIC connection close by default in ConnectivityService This feature will be controlled by the caller. Cronet calls the register/unregisterQuicConnectionClosePayload APIs only when the Chromium experiment flag is enabled (http://crrev.com/c/6421621/). This CL also updates testRegisterQuicConnectionClosePayload to be skipped on U or older releases since FIREWALL_CHAIN_BACKGROUND is supported on V or higher releases. Flag: EXEMPT guarded by chromium flag Bug: 311792075 Test: TH Change-Id: Ib008e63c585cfe8775b25783cd55b0873bb5e2f0 --- service/src/com/android/server/ConnectivityService.java | 5 ++++- .../net/src/android/net/cts/ConnectivityManagerTest.java | 8 ++++++-- .../java/com/android/server/ConnectivityServiceTest.java | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index dd1edfeecf..32df8237d2 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -2157,7 +2157,10 @@ public class ConnectivityService extends IConnectivityManager.Stub { mL2capNetworkProvider = mDeps.makeL2capNetworkProvider(mContext); - mCloseQuicConnection = mDeps.isFeatureEnabled(context, CLOSE_QUIC_CONNECTION); + // QUIC connection close is triggered by freezer (U+) or background firewall chain (V+). + // TODO: Allow other firewall chains to close QUIC connection and enable this flag on T+ + mCloseQuicConnection = mDeps.isAtLeastU() + && mDeps.isFeatureNotChickenedOut(context, CLOSE_QUIC_CONNECTION); if (mCloseQuicConnection) { mQuicConnectionCloser = mDeps.makeQuicConnectionCloser(mNetworkForNetId, mHandler); } else { diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 3a3b256fc9..2ddaa50245 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -4358,8 +4358,11 @@ public class ConnectivityManagerTest { }); } + // This test is skipped on U and older releases because QUIC connection close can be triggered + // by the freezer (U+) or the background firewall chain (V+), but the freezer cannot be tested. + // TODO: Enable this test on T+ once other firewall chains can trigger QUIC connection close. @Test - @IgnoreUpTo(Build.VERSION_CODES.R) + @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) @ConnectivityModuleTest @AppModeFull(reason = "Cannot create test network in instant app mode") public void testRegisterQuicConnectionClosePayload_blockNetwork() throws Exception { @@ -4384,8 +4387,9 @@ public class ConnectivityManagerTest { true /* blockNetwork */, false /* expectPacketSent */); } + // TODO: Enable this test on T+ once other firewall chains can trigger QUIC connection close. @Test - @IgnoreUpTo(Build.VERSION_CODES.R) + @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) @ConnectivityModuleTest @AppModeFull(reason = "Cannot create test network in instant app mode") public void testRegisterQuicConnectionClosePayload_closeSocket() throws Exception { diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index 63d014aad9..d3ff5d133c 100755 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -2188,7 +2188,6 @@ public class ConnectivityServiceTest { case ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS: case ConnectivityFlags.QUEUE_CALLBACKS_FOR_FROZEN_APPS: case ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN: - case ConnectivityFlags.CLOSE_QUIC_CONNECTION: case ConnectivityService.KEY_DESTROY_FROZEN_SOCKETS_VERSION: return true; default: @@ -2209,6 +2208,7 @@ public class ConnectivityServiceTest { case ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS: case ConnectivityFlags.QUEUE_CALLBACKS_FOR_FROZEN_APPS: case ConnectivityFlags.QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER: + case ConnectivityFlags.CLOSE_QUIC_CONNECTION: return true; default: throw new UnsupportedOperationException("Unknown flag " + name From f56926095e06a382d3a14182b5c02228d899d584 Mon Sep 17 00:00:00 2001 From: Motomu Utsumi Date: Fri, 25 Apr 2025 15:15:45 +0900 Subject: [PATCH 2/2] Allow QuicConnectionCloser to close loopback QUIC connection The test for closing QUIC connection feature runs QuicTestServer on the device to ensure the server tears down the connection after the registered payload is sent to the server. It is difficult to verify this with public servers because there is no way to verify server internal state. Before this CL, QuicConnectionCloser only closed connection when the network's linkproperties contained the source address of the QUIC connection. This was to avoid sending packets from unused addresses. However, this made it difficult to verify the feature in tests because QuicTestServer listens on loopback address. This could be solved by using test networks. However, this requires a good amount of work, including updating QuicTestServer to read packets from a tun file descriptor instead of a UDP socket, and updating Cronet to allow overriding hostname resolution when the HttpEngine is bound to a network. So, this CL allows QuicConnectionCloser to close loopback QUIC connections. The impact of this change should be negligible because running a QUIC server on the device is uncommon. Also, even if the connection is closed, Cronet reconnects to the server quickly. Flag: EXEMPT guarded by chromium flag Test: TH Bug: 311792075 Change-Id: I579b3cd912c47f15498527d7dc49e4169b9fe75f --- .../android/server/connectivity/QuicConnectionCloser.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/service/src/com/android/server/connectivity/QuicConnectionCloser.java b/service/src/com/android/server/connectivity/QuicConnectionCloser.java index c582d60f4f..c4fe5b8621 100644 --- a/service/src/com/android/server/connectivity/QuicConnectionCloser.java +++ b/service/src/com/android/server/connectivity/QuicConnectionCloser.java @@ -254,8 +254,14 @@ public class QuicConnectionCloser { Log.d(TAG, "Close QUIC socket for " + info + ", destroySocket=" + destroySocket); final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(info.netId); - if (nai == null || !nai.linkProperties.getAddresses().contains(info.src.getAddress())) { + if (nai == null) return; // The network has gone away already + + final boolean isLoopbackConnection = info.dst.getAddress().isLoopbackAddress(); + final boolean lpContainsSourceAddress = + nai.linkProperties.getAddresses().contains(info.src.getAddress()); + if (!isLoopbackConnection && !lpContainsSourceAddress) { // The device should not send a packet with an unused source address. + // Loopback connections are closed exceptionally to simplify device local testing. return; }