From 444481ffd91a02dfad2dc6222fce88fe4453090e Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 08:46:07 -0800
Subject: [PATCH 01/54] feat: Android support

WIP
---
 .github/workflows/check.yml | 50 +++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 0536afec..4906c826 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -405,3 +405,53 @@ jobs:
         with:
           token: ${{ secrets.GITHUB_TOKEN }}
       - run: cargo update -w --locked
+
+  check-android:
+    runs-on: ubuntu-latest
+
+    strategy:
+      matrix:
+        target: [x86_64-linux-android, i686-linux-android]
+        emulator-arch: [x86_64, x86]
+        api-level: [26, 25]
+        exclude:
+          - target: x86_64-linux-android
+            emulator-arch: x86
+          - target: i686-linux-android
+            emulator-arch: x86_64
+
+    steps:
+
+    - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+      with:
+        persist-credentials: false
+
+    - uses: ./.github/actions/rust
+      with:
+        version: stable
+        targets: ${{ matrix.target }}
+        tools: cargo-ndk
+        token: ${{ secrets.GITHUB_TOKEN }}
+
+    - run: cargo ndk -t ${{ matrix.target }} test --no-run
+
+    - name: Enable KVM group perms
+      run: |
+        echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
+        sudo udevadm control --reload-rules
+        sudo udevadm trigger --name-match=kvm
+
+    - uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.33.0
+      with:
+        api-level: ${{ matrix.api-level }}
+        arch: ${{ matrix.emulator-arch }}
+        script: |
+          adb wait-for-device
+          while [[ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]]; do sleep 1; done
+          any_failures=0
+          for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
+              adb push "$test" /data/local/tmp/
+              adb shell chmod +x /data/local/tmp/$(basename "$test")
+              adb shell API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || any_failures=1
+          done
+          exit $any_failures

From 12333ddc5ac618a89a381f06b85d0abad5f35274 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 08:48:42 -0800
Subject: [PATCH 02/54] Fix

---
 .github/workflows/check.yml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 4906c826..a51b5db1 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -426,7 +426,14 @@ jobs:
       with:
         persist-credentials: false
 
-    - uses: ./.github/actions/rust
+    - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+      with:
+        repository: mozilla/neqo
+        sparse-checkout: |
+          .github/actions/rust
+        path: neqo
+        persist-credentials: false
+    - uses: ./neqo/.github/actions/rust
       with:
         version: stable
         targets: ${{ matrix.target }}

From aec78c03b9daa1373f76b445c995e2abba31c461 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 15:14:47 -0600
Subject: [PATCH 03/54] Debug

---
 .github/workflows/check.yml | 2 +-
 build.rs                    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index a51b5db1..8156f903 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -440,7 +440,7 @@ jobs:
         tools: cargo-ndk
         token: ${{ secrets.GITHUB_TOKEN }}
 
-    - run: cargo ndk -t ${{ matrix.target }} test --no-run
+    - run: cargo -vv ndk -t ${{ matrix.target }} test --no-run
 
     - name: Enable KVM group perms
       run: |
diff --git a/build.rs b/build.rs
index 56ef74e7..041d0bcf 100644
--- a/build.rs
+++ b/build.rs
@@ -36,7 +36,7 @@ const fn clang_args() -> Vec<String> {
 
 fn bindgen() {
     let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set");
-
+    eprintln!("target_os: {target_os}");
     // Platforms currently not supported.
     //
     // See <https://github.com/mozilla/mtu/issues/82>.

From cf94ab2e4d3d7ae8f12da92dbe7bf69ffcacdf54 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 15:39:11 -0600
Subject: [PATCH 04/54] Again

---
 .github/workflows/check.yml | 2 +-
 build.rs                    | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 8156f903..25aa3202 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -440,7 +440,7 @@ jobs:
         tools: cargo-ndk
         token: ${{ secrets.GITHUB_TOKEN }}
 
-    - run: cargo -vv ndk -t ${{ matrix.target }} test --no-run
+    - run: cargo ndk -vv -t ${{ matrix.target }} test --no-run
 
     - name: Enable KVM group perms
       run: |
diff --git a/build.rs b/build.rs
index 041d0bcf..26659442 100644
--- a/build.rs
+++ b/build.rs
@@ -6,7 +6,7 @@
 
 #![allow(clippy::unwrap_used)] // OK in build scripts.
 
-use std::env;
+use std::{env, fs};
 
 const BINDINGS: &str = "bindings.rs";
 
@@ -86,6 +86,8 @@ fn bindgen() {
         .write_to_file(out_path.clone())
         .expect("Couldn't write bindings!");
     println!("cargo:rustc-env=BINDINGS={}", out_path.display());
+    let c = fs::read_to_string(out_path).unwrap();
+    eprintln!("bindings.rs: {c}");
 }
 
 fn main() {

From 565a913fa058ad16610467f2a0287ae38988d9c5 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 15:42:14 -0600
Subject: [PATCH 05/54] Again

---
 .github/workflows/check.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 25aa3202..157beef1 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -440,7 +440,7 @@ jobs:
         tools: cargo-ndk
         token: ${{ secrets.GITHUB_TOKEN }}
 
-    - run: cargo ndk -vv -t ${{ matrix.target }} test --no-run
+    - run: cargo -vv ndk -t ${{ matrix.target }} test --no-run
 
     - name: Enable KVM group perms
       run: |
@@ -454,7 +454,7 @@ jobs:
         arch: ${{ matrix.emulator-arch }}
         script: |
           adb wait-for-device
-          while [[ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]]; do sleep 1; done
+          while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
           any_failures=0
           for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
               adb push "$test" /data/local/tmp/

From 8ed11fcb7a8a9b7ee5611317cf440182970197a7 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 15:45:34 -0600
Subject: [PATCH 06/54] Again

---
 .github/workflows/check.yml | 4 +++-
 build.rs                    | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 157beef1..b3d6ed2c 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -440,7 +440,9 @@ jobs:
         tools: cargo-ndk
         token: ${{ secrets.GITHUB_TOKEN }}
 
-    - run: cargo -vv ndk -t ${{ matrix.target }} test --no-run
+    - run: |
+        cargo clean
+        cargo -vv ndk -t ${{ matrix.target }} test --no-run
 
     - name: Enable KVM group perms
       run: |
diff --git a/build.rs b/build.rs
index 26659442..2b862cf8 100644
--- a/build.rs
+++ b/build.rs
@@ -36,7 +36,7 @@ const fn clang_args() -> Vec<String> {
 
 fn bindgen() {
     let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set");
-    eprintln!("target_os: {target_os}");
+
     // Platforms currently not supported.
     //
     // See <https://github.com/mozilla/mtu/issues/82>.

From ded33c58b46a5640f15096f9569709edd598e23f Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 15:48:29 -0600
Subject: [PATCH 07/54] Again

---
 .github/workflows/check.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index b3d6ed2c..1f83bbe8 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -441,7 +441,8 @@ jobs:
         token: ${{ secrets.GITHUB_TOKEN }}
 
     - run: |
-        cargo clean
+        echo "RUSTFLAGS=''" >> $GITHUB_ENV
+        export RUSTFLAGS=""
         cargo -vv ndk -t ${{ matrix.target }} test --no-run
 
     - name: Enable KVM group perms

From 9c759e468b48e660ac93012d6826114e4f00e89c Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 15:58:35 -0600
Subject: [PATCH 08/54] Again

---
 .github/workflows/check.yml | 4 ++--
 build.rs                    | 9 ++++++---
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 1f83bbe8..e7f211da 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -441,8 +441,8 @@ jobs:
         token: ${{ secrets.GITHUB_TOKEN }}
 
     - run: |
-        echo "RUSTFLAGS=''" >> $GITHUB_ENV
-        export RUSTFLAGS=""
+        # echo "RUSTFLAGS=''" >> "$GITHUB_ENV"
+        # export RUSTFLAGS=""
         cargo -vv ndk -t ${{ matrix.target }} test --no-run
 
     - name: Enable KVM group perms
diff --git a/build.rs b/build.rs
index 2b862cf8..57d5900f 100644
--- a/build.rs
+++ b/build.rs
@@ -6,7 +6,7 @@
 
 #![allow(clippy::unwrap_used)] // OK in build scripts.
 
-use std::{env, fs};
+use std::env;
 
 const BINDINGS: &str = "bindings.rs";
 
@@ -48,6 +48,11 @@ fn bindgen() {
         return;
     }
 
+    if target_os.as_str().ends_with("android") {
+        env::var("BINDGEN_EXTRA_CLANG_ARGS")
+            .expect("Need to set BINDGEN_EXTRA_CLANG_ARGS=--sysroot=/path/to/your/ndk/sysroot");
+    }
+
     let bindings = if matches!(target_os.as_str(), "linux" | "android") {
         bindgen::Builder::default()
             .header_contents("rtnetlink.h", "#include <linux/rtnetlink.h>")
@@ -86,8 +91,6 @@ fn bindgen() {
         .write_to_file(out_path.clone())
         .expect("Couldn't write bindings!");
     println!("cargo:rustc-env=BINDINGS={}", out_path.display());
-    let c = fs::read_to_string(out_path).unwrap();
-    eprintln!("bindings.rs: {c}");
 }
 
 fn main() {

From a1bcef7c93853b0503b29eb4a7b7fa9d542f0d8d Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 16:08:51 -0600
Subject: [PATCH 09/54] Again

---
 build.rs | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/build.rs b/build.rs
index 57d5900f..13c5eb9f 100644
--- a/build.rs
+++ b/build.rs
@@ -11,7 +11,7 @@ use std::env;
 const BINDINGS: &str = "bindings.rs";
 
 #[cfg(feature = "gecko")]
-fn clang_args() -> Vec<String> {
+fn clang_args(_target_os: &str) -> Vec<String> {
     use mozbuild::{config::BINDGEN_SYSTEM_FLAGS, TOPOBJDIR};
 
     let mut flags: Vec<String> = BINDGEN_SYSTEM_FLAGS.iter().map(|s| s.to_string()).collect();
@@ -30,8 +30,15 @@ fn clang_args() -> Vec<String> {
 }
 
 #[cfg(not(feature = "gecko"))]
-const fn clang_args() -> Vec<String> {
-    Vec::new()
+fn clang_args(target_os: &str) -> Vec<String> {
+    match target_os {
+        "android" => {
+            let sysroot =
+                env::var("CARGO_NDK_SYSROOT_PATH").expect("CARGO_NDK_SYSROOT_PATH was not set");
+            vec![format!("--sysroot={sysroot}")]
+        }
+        _ => Vec::new(),
+    }
 }
 
 fn bindgen() {
@@ -48,11 +55,6 @@ fn bindgen() {
         return;
     }
 
-    if target_os.as_str().ends_with("android") {
-        env::var("BINDGEN_EXTRA_CLANG_ARGS")
-            .expect("Need to set BINDGEN_EXTRA_CLANG_ARGS=--sysroot=/path/to/your/ndk/sysroot");
-    }
-
     let bindings = if matches!(target_os.as_str(), "linux" | "android") {
         bindgen::Builder::default()
             .header_contents("rtnetlink.h", "#include <linux/rtnetlink.h>")
@@ -70,7 +72,7 @@ fn bindgen() {
     };
 
     let bindings = bindings
-        .clang_args(clang_args())
+        .clang_args(clang_args(&target_os))
         // Tell cargo to invalidate the built crate whenever any of the
         // included header files changed.
         .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))

From c466428860f7a3dffab723d5c76245211ada1f90 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 16:11:25 -0600
Subject: [PATCH 10/54] Again

---
 .github/workflows/check.yml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index e7f211da..7760bcb2 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -441,8 +441,9 @@ jobs:
         token: ${{ secrets.GITHUB_TOKEN }}
 
     - run: |
-        # echo "RUSTFLAGS=''" >> "$GITHUB_ENV"
-        # export RUSTFLAGS=""
+        # FIXME: Remove resetting RUSTFLAGS once Android support for neqo has landed.
+        echo "RUSTFLAGS=''" >> "$GITHUB_ENV"
+        export RUSTFLAGS=""
         cargo -vv ndk -t ${{ matrix.target }} test --no-run
 
     - name: Enable KVM group perms

From 0a4a52aadd0a5366d4415c018e3f0e0ae6e525fb Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 16:17:41 -0600
Subject: [PATCH 11/54] Again

---
 .github/workflows/check.yml | 3 ++-
 README.md                   | 2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 7760bcb2..8f53cfdd 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -460,7 +460,8 @@ jobs:
           adb wait-for-device
           while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
           any_failures=0
-          for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
+          find target -ls
+          for test in $(find target/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
               adb push "$test" /data/local/tmp/
               adb shell chmod +x /data/local/tmp/$(basename "$test")
               adb shell API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || any_failures=1
diff --git a/README.md b/README.md
index c116263d..33ff57f8 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,7 @@ This crate exports a single function `interface_and_mtu` that returns the name a
 of the outgoing network interface towards a remote destination identified by an `IpAddr`.
 
 ## Example
+
 ```rust
 let destination = IpAddr::V4(Ipv4Addr::LOCALHOST);
 let (name, mtu): (String, usize) = mtu::interface_and_mtu(destination).unwrap();
@@ -24,6 +25,7 @@ println!("MTU towards {destination} is {mtu} on {name}");
 ## Supported Platforms
 
 * Linux
+* Android
 * macOS
 * Windows
 * FreeBSD

From 3a836e9ff90301baa4b9a9918f22f9147620ee2a Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 16:25:07 -0600
Subject: [PATCH 12/54] Again

---
 .github/workflows/check.yml | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 8f53cfdd..6f319399 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -440,7 +440,10 @@ jobs:
         tools: cargo-ndk
         token: ${{ secrets.GITHUB_TOKEN }}
 
-    - run: |
+    - env:
+        TARGET: ${{ matrix.target }}
+      run: |
+        echo "TARGET=$TARGET" >> "$GITHUB_ENV"
         # FIXME: Remove resetting RUSTFLAGS once Android support for neqo has landed.
         echo "RUSTFLAGS=''" >> "$GITHUB_ENV"
         export RUSTFLAGS=""
@@ -460,8 +463,8 @@ jobs:
           adb wait-for-device
           while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
           any_failures=0
-          find target -ls
-          for test in $(find target/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
+          find target/$TARGET -ls
+          for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
               adb push "$test" /data/local/tmp/
               adb shell chmod +x /data/local/tmp/$(basename "$test")
               adb shell API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || any_failures=1

From b5d0954be5434f26571221bff739d128dace3da1 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 16:26:13 -0600
Subject: [PATCH 13/54] Again

---
 .github/workflows/check.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 6f319399..a0a6f191 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -464,6 +464,7 @@ jobs:
           while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
           any_failures=0
           find target/$TARGET -ls
+          find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"
           for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
               adb push "$test" /data/local/tmp/
               adb shell chmod +x /data/local/tmp/$(basename "$test")

From 738dff545c44f0cd109ae09474f42574d35b9d78 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 16:30:34 -0600
Subject: [PATCH 14/54] Again

---
 .github/workflows/check.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index a0a6f191..8207c0ad 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -463,8 +463,8 @@ jobs:
           adb wait-for-device
           while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
           any_failures=0
-          find target/$TARGET -ls
           find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"
+          echo XXX
           for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
               adb push "$test" /data/local/tmp/
               adb shell chmod +x /data/local/tmp/$(basename "$test")

From 265ac630224e76ef5ffefe33793fa14ccf78d4df Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 16:36:29 -0600
Subject: [PATCH 15/54] Again

---
 .github/workflows/check.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 8207c0ad..1a29ff57 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -463,7 +463,8 @@ jobs:
           adb wait-for-device
           while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
           any_failures=0
-          find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"
+          find target/$TARGET/debug/deps/ -type f -executable
+          #  ! -name "*.so" -name "*-*"
           echo XXX
           for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
               adb push "$test" /data/local/tmp/

From 490a120061960cc05fcb67d094110fb0c4c90c5b Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sun, 2 Mar 2025 16:41:48 -0600
Subject: [PATCH 16/54] Again

---
 .github/workflows/check.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 1a29ff57..71fe9b52 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -463,8 +463,8 @@ jobs:
           adb wait-for-device
           while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
           any_failures=0
-          find target/$TARGET/debug/deps/ -type f -executable
-          #  ! -name "*.so" -name "*-*"
+          find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so"
+          #-name "*-*"
           echo XXX
           for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
               adb push "$test" /data/local/tmp/

From 7fa9d9c3f35711d2ac3f54a3379ff41f9aba79df Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Mon, 3 Mar 2025 12:24:37 +0200
Subject: [PATCH 17/54] Again

---
 .github/workflows/check.yml | 2 +-
 src/lib.rs                  | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 71fe9b52..be4e8a1f 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -463,7 +463,7 @@ jobs:
           adb wait-for-device
           while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
           any_failures=0
-          find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so"
+          find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"
           #-name "*-*"
           echo XXX
           for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
diff --git a/src/lib.rs b/src/lib.rs
index 14fcc2aa..29b5c377 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,6 +14,7 @@
 //! of the outgoing network interface towards a remote destination identified by an `IpAddr`.
 //!
 //! # Example
+//!
 //! ```
 //! # use std::net::{IpAddr, Ipv4Addr};
 //! let destination = IpAddr::V4(Ipv4Addr::LOCALHOST);
@@ -24,6 +25,7 @@
 //! # Supported Platforms
 //!
 //! * Linux
+//! * Android
 //! * macOS
 //! * Windows
 //! * FreeBSD

From 130d83d858679c13201cb15b6eaac516b4b43a00 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Mon, 3 Mar 2025 12:30:52 +0200
Subject: [PATCH 18/54] Again

---
 .github/workflows/check.yml | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index be4e8a1f..1be60b8e 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -463,12 +463,11 @@ jobs:
           adb wait-for-device
           while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
           any_failures=0
-          find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"
-          #-name "*-*"
-          echo XXX
-          for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
-              adb push "$test" /data/local/tmp/
-              adb shell chmod +x /data/local/tmp/$(basename "$test")
-              adb shell API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || any_failures=1
+          find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*" | \
+          while IFS= read -r test; do
+            echo "Running $test on emulator..."
+            adb push "$test" /data/local/tmp/
+            adb shell chmod +x /data/local/tmp/$(basename "$test")
+            adb shell API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || any_failures=1
           done
           exit $any_failures

From 878118468c6c9f156a1b4a6ba21aaf5aa70ee80e Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Mon, 3 Mar 2025 12:36:40 +0200
Subject: [PATCH 19/54] Again

---
 .github/workflows/check.yml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 1be60b8e..7dc3ec7b 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -463,8 +463,7 @@ jobs:
           adb wait-for-device
           while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
           any_failures=0
-          find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*" | \
-          while IFS= read -r test; do
+          find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*" | while IFS= read -r test; do
             echo "Running $test on emulator..."
             adb push "$test" /data/local/tmp/
             adb shell chmod +x /data/local/tmp/$(basename "$test")

From f03af66ab1bb8bff444741cef7c19f45e2005fb6 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Mon, 3 Mar 2025 12:46:05 +0200
Subject: [PATCH 20/54] Again

---
 .github/workflows/check.yml | 34 ++++++++++++++++++----------------
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 7dc3ec7b..2abba43b 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -440,33 +440,35 @@ jobs:
         tools: cargo-ndk
         token: ${{ secrets.GITHUB_TOKEN }}
 
-    - env:
-        TARGET: ${{ matrix.target }}
-      run: |
-        echo "TARGET=$TARGET" >> "$GITHUB_ENV"
+    - run: |
         # FIXME: Remove resetting RUSTFLAGS once Android support for neqo has landed.
         echo "RUSTFLAGS=''" >> "$GITHUB_ENV"
         export RUSTFLAGS=""
         cargo -vv ndk -t ${{ matrix.target }} test --no-run
 
-    - name: Enable KVM group perms
+    - env:
+        TARGET: ${{ matrix.target }}
       run: |
         echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
         sudo udevadm control --reload-rules
         sudo udevadm trigger --name-match=kvm
+        echo "TARGET=$TARGET" >> "$GITHUB_ENV"
+        cat <<'EOF' > rust-android-run-tests-on-emulator.sh
+        #!/bin/bash
+        set -e
+        adb wait-for-device
+        while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
+        any_failures=0
+        for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
+          adb push "$test" /data/local/tmp/
+          adb shell chmod +x /data/local/tmp/$(basename "$test")
+          adb shell API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || any_failures=1
+        done
+        exit $any_failures
+        EOF
 
     - uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.33.0
       with:
         api-level: ${{ matrix.api-level }}
         arch: ${{ matrix.emulator-arch }}
-        script: |
-          adb wait-for-device
-          while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
-          any_failures=0
-          find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*" | while IFS= read -r test; do
-            echo "Running $test on emulator..."
-            adb push "$test" /data/local/tmp/
-            adb shell chmod +x /data/local/tmp/$(basename "$test")
-            adb shell API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || any_failures=1
-          done
-          exit $any_failures
+        script: rust-android-run-tests-on-emulator.sh

From 7cc644403d8a837744ab76abe44ef4097adf159f Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Mon, 3 Mar 2025 12:50:39 +0200
Subject: [PATCH 21/54] Again

---
 .github/workflows/check.yml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 2abba43b..7f626c41 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -453,7 +453,7 @@ jobs:
         sudo udevadm control --reload-rules
         sudo udevadm trigger --name-match=kvm
         echo "TARGET=$TARGET" >> "$GITHUB_ENV"
-        cat <<'EOF' > rust-android-run-tests-on-emulator.sh
+        cat <<'EOF' > /tmp/rust-android-run-tests-on-emulator.sh
         #!/bin/bash
         set -e
         adb wait-for-device
@@ -466,9 +466,10 @@ jobs:
         done
         exit $any_failures
         EOF
+        cat /tmp/rust-android-run-tests-on-emulator.sh
 
     - uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.33.0
       with:
         api-level: ${{ matrix.api-level }}
         arch: ${{ matrix.emulator-arch }}
-        script: rust-android-run-tests-on-emulator.sh
+        script: /tmp/rust-android-run-tests-on-emulator.sh

From 661030289ae51239c0a3d76575ec2540a4195316 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Mon, 3 Mar 2025 12:53:33 +0200
Subject: [PATCH 22/54] Again

---
 .github/workflows/check.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 7f626c41..11b2fd5b 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -466,7 +466,7 @@ jobs:
         done
         exit $any_failures
         EOF
-        cat /tmp/rust-android-run-tests-on-emulator.sh
+        chmod a+x /tmp/rust-android-run-tests-on-emulator.sh
 
     - uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.33.0
       with:

From f489da7231d22f5e758602e19f268193e54d1d7a Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Mon, 3 Mar 2025 13:05:11 +0200
Subject: [PATCH 23/54] Bump version

---
 .github/workflows/check.yml | 1 +
 Cargo.lock                  | 2 +-
 Cargo.toml                  | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 11b2fd5b..b1a2350f 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -433,6 +433,7 @@ jobs:
           .github/actions/rust
         path: neqo
         persist-credentials: false
+
     - uses: ./neqo/.github/actions/rust
       with:
         version: stable
diff --git a/Cargo.lock b/Cargo.lock
index eac5a62b..0ddf0505 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -138,7 +138,7 @@ checksum = "903970ae2f248d7275214cf8f387f8ba0c4ea7e3d87a320e85493db60ce28616"
 
 [[package]]
 name = "mtu"
-version = "0.2.6"
+version = "0.2.7"
 dependencies = [
  "bindgen",
  "cfg_aliases",
diff --git a/Cargo.toml b/Cargo.toml
index 32f9742c..bb26dcda 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ homepage = "https://github.com/mozilla/mtu/"
 repository = "https://github.com/mozilla/mtu/"
 authors = ["The Mozilla Necko Team <necko@mozilla.com>"]
 readme = "README.md"
-version = "0.2.6"
+version = "0.2.7"
 edition = "2021"
 license = "MIT OR Apache-2.0"
 # Don't increase beyond what Firefox is currently using:

From 0bc74e8f28f6808f7471ecda8459996db3158562 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Mon, 3 Mar 2025 13:11:48 +0200
Subject: [PATCH 24/54] Again

---
 .github/workflows/check.yml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 26cdee80..b4ca6880 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -457,6 +457,7 @@ jobs:
         cat <<'EOF' > /tmp/rust-android-run-tests-on-emulator.sh
         #!/bin/bash
         set -e
+        export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
         any_failures=0
@@ -468,6 +469,7 @@ jobs:
         exit $any_failures
         EOF
         chmod a+x /tmp/rust-android-run-tests-on-emulator.sh
+        ifconfig -a
 
     - uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.33.0
       with:

From 56b4bf21451c3db53e5e767af441c0eb91acbd0f Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 09:37:22 +0200
Subject: [PATCH 25/54] armv7

---
 .github/workflows/check.yml | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index b4ca6880..eca99186 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -411,17 +411,20 @@ jobs:
 
     strategy:
       matrix:
-        target: [x86_64-linux-android, i686-linux-android]
-        emulator-arch: [x86_64, x86]
-        api-level: [26, 25]
-        exclude:
+        include:
           - target: x86_64-linux-android
-            emulator-arch: x86
-          - target: i686-linux-android
             emulator-arch: x86_64
+            # Note that x86_64 image is only available for API 21+. See
+            # https://github.com/ReactiveCircus/android-emulator-runner?tab=readme-ov-file#configurations.
+            api-level: 21
+          - target: armv7-linux-android
+            emulator-arch: x86_64
+            api-level: 21
+          - target: i686-linux-android
+            emulator-arch: x86
+            api-level: 21
 
     steps:
-
     - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
       with:
         persist-credentials: false

From 29dee76e83a64ed6efa37ec6e6012f7a9f137b97 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 09:41:25 +0200
Subject: [PATCH 26/54] armv7-linux-androideabi

---
 .github/workflows/check.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index eca99186..a5ad2b9e 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -417,7 +417,7 @@ jobs:
             # Note that x86_64 image is only available for API 21+. See
             # https://github.com/ReactiveCircus/android-emulator-runner?tab=readme-ov-file#configurations.
             api-level: 21
-          - target: armv7-linux-android
+          - target: armv7-linux-androideabi
             emulator-arch: x86_64
             api-level: 21
           - target: i686-linux-android

From 99b1118a020d97b1d15b211c20275b910e89e303 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 09:57:22 +0200
Subject: [PATCH 27/54] Again

---
 .github/workflows/check.yml | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index a5ad2b9e..c3cfa19a 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -408,6 +408,9 @@ jobs:
 
   check-android:
     runs-on: ubuntu-latest
+    env:
+      NDK_VERSION: r27c
+      API_LEVEL: 21
 
     strategy:
       matrix:
@@ -416,13 +419,10 @@ jobs:
             emulator-arch: x86_64
             # Note that x86_64 image is only available for API 21+. See
             # https://github.com/ReactiveCircus/android-emulator-runner?tab=readme-ov-file#configurations.
-            api-level: 21
           - target: armv7-linux-androideabi
-            emulator-arch: x86_64
-            api-level: 21
+            emulator-arch: arm64-v8
           - target: i686-linux-android
             emulator-arch: x86
-            api-level: 21
 
     steps:
     - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -437,6 +437,14 @@ jobs:
         path: neqo
         persist-credentials: false
 
+    - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
+      with:
+        distribution: 'zulu'
+        java-version: '21'
+
+    - uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3.2.2
+    - run: sdkmanager --install "ndk;${{ env.NDK_VERSION }}"
+
     - uses: ./neqo/.github/actions/rust
       with:
         version: stable
@@ -456,7 +464,6 @@ jobs:
         echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
         sudo udevadm control --reload-rules
         sudo udevadm trigger --name-match=kvm
-        echo "TARGET=$TARGET" >> "$GITHUB_ENV"
         cat <<'EOF' > /tmp/rust-android-run-tests-on-emulator.sh
         #!/bin/bash
         set -e
@@ -476,6 +483,9 @@ jobs:
 
     - uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.33.0
       with:
-        api-level: ${{ matrix.api-level }}
+        api-level: ${{ env.API_LEVEL }}
         arch: ${{ matrix.emulator-arch }}
+        ndk: ${{ env.NDK_VERSION }}
         script: /tmp/rust-android-run-tests-on-emulator.sh
+      env:
+        TARGET: ${{ matrix.target }}

From c4ef55c162aedabf3ee736f69890510f87ebae3b Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 10:08:30 +0200
Subject: [PATCH 28/54] Again

---
 .github/workflows/check.yml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index c3cfa19a..0513ee93 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -409,7 +409,9 @@ jobs:
   check-android:
     runs-on: ubuntu-latest
     env:
-      NDK_VERSION: r27c
+      # https://searchfox.org/mozilla-central/search?q=NDK_VERSION =&path=python/mozboot/mozboot/android.py
+      NDK_VERSION: 27.2.12479018 # r27c
+      # https://searchfox.org/mozilla-central/search?q=\bapi_level=&path=taskcluster/scripts/misc/build-llvm-common.sh&regexp=true
       API_LEVEL: 21
 
     strategy:

From 5e899b29b9e8a6868f39bfe1dddc96379e96ed4b Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 10:15:20 +0200
Subject: [PATCH 29/54] More

---
 .github/workflows/check.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 0513ee93..4782c1dc 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -486,7 +486,7 @@ jobs:
     - uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.33.0
       with:
         api-level: ${{ env.API_LEVEL }}
-        arch: ${{ matrix.emulator-arch }}
+        arch: ${{ matrix.emulator-arch == 'arm64-v8' && 'arm64-v8a' || matrix.emulator-arch }}
         ndk: ${{ env.NDK_VERSION }}
         script: /tmp/rust-android-run-tests-on-emulator.sh
       env:

From 8565ab542f343dcb2dc796cfc80e7d8d5e3dc54c Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 10:22:02 +0200
Subject: [PATCH 30/54] ifconfig

---
 .github/workflows/check.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 4782c1dc..7af3f8eb 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -469,6 +469,7 @@ jobs:
         cat <<'EOF' > /tmp/rust-android-run-tests-on-emulator.sh
         #!/bin/bash
         set -e
+        ifconfig -a
         export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
@@ -481,7 +482,6 @@ jobs:
         exit $any_failures
         EOF
         chmod a+x /tmp/rust-android-run-tests-on-emulator.sh
-        ifconfig -a
 
     - uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.33.0
       with:

From 29ef61a8677916b63b814e9f9013816d6fdc3346 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 10:31:08 +0200
Subject: [PATCH 31/54] Again

---
 .github/workflows/check.yml | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 7af3f8eb..36dc3b3a 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -441,8 +441,8 @@ jobs:
 
     - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
       with:
-        distribution: 'zulu'
-        java-version: '21'
+        distribution: zulu
+        java-version: 23
 
     - uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3.2.2
     - run: sdkmanager --install "ndk;${{ env.NDK_VERSION }}"
@@ -469,6 +469,7 @@ jobs:
         cat <<'EOF' > /tmp/rust-android-run-tests-on-emulator.sh
         #!/bin/bash
         set -e
+        echo Heya
         ifconfig -a
         export GITHUB_ACTIONS=1
         adb wait-for-device
@@ -479,6 +480,7 @@ jobs:
           adb shell chmod +x /data/local/tmp/$(basename "$test")
           adb shell API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || any_failures=1
         done
+        echo "Failures: $any_failures"
         exit $any_failures
         EOF
         chmod a+x /tmp/rust-android-run-tests-on-emulator.sh

From b2759a0a1b6b0b7c6e24b30ab8677e79377f3658 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 10:41:54 +0200
Subject: [PATCH 32/54] Debug

---
 .github/workflows/check.yml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 36dc3b3a..4c786a97 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -471,9 +471,15 @@ jobs:
         set -e
         echo Heya
         ifconfig -a
+        adb shell netcfg
+        adb shell false || echo failed false
+        adb shell true || echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
-        while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
+        while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do
+          adb devices
+          sleep 1;
+        done
         any_failures=0
         for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
           adb push "$test" /data/local/tmp/

From 77297357e05ffd6778f6d5088c4fdc22abc21727 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 10:47:53 +0200
Subject: [PATCH 33/54] Again

---
 .github/workflows/check.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 4c786a97..965c5aad 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -297,7 +297,7 @@ jobs:
             pkg install -y curl llvm
           run: | # This executes as user
             set -e
-            sh rustup.sh --default-toolchain nightly --profile minimal --component clippy llvm-tools -y
+            sh rustup.sh --default-toolchain nightly --profile minimal --component clippy,llvm-tools -y
             . "$HOME/.cargo/env"
             cargo check --all-targets
             cargo clippy -- -D warnings
@@ -341,7 +341,7 @@ jobs:
             pkgin -y install curl clang
           run: | # This executes as user
             set -e
-            sh rustup.sh --default-toolchain nightly --profile minimal --component clippy llvm-tools -y
+            sh rustup.sh --default-toolchain nightly --profile minimal --component clippy,llvm-tools -y
             . "$HOME/.cargo/env"
             cargo check --all-targets
             cargo clippy -- -D warnings

From e52751459a08034f45e887a1d3753a2fa8a9a542 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 10:54:12 +0200
Subject: [PATCH 34/54] Again

---
 .github/workflows/check.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 965c5aad..fa380e1b 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -470,8 +470,8 @@ jobs:
         #!/bin/bash
         set -e
         echo Heya
-        ifconfig -a
         adb shell netcfg
+        adb shell ip addr show
         adb shell false || echo failed false
         adb shell true || echo failed true
         export GITHUB_ACTIONS=1
@@ -480,6 +480,7 @@ jobs:
           adb devices
           sleep 1;
         done
+        echo Gogogo
         any_failures=0
         for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
           adb push "$test" /data/local/tmp/

From 9d47a94ed2e54162901e900d42c2da76d28f1ec1 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 11:10:42 +0200
Subject: [PATCH 35/54] Again

---
 .github/workflows/check.yml | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index fa380e1b..cb96f9c5 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -469,11 +469,9 @@ jobs:
         cat <<'EOF' > /tmp/rust-android-run-tests-on-emulator.sh
         #!/bin/bash
         set -e
-        echo Heya
-        adb shell netcfg
         adb shell ip addr show
-        adb shell false || echo failed false
-        adb shell true || echo failed true
+        adb shell "false; echo \$?" || echo failed false
+        adb shell "true; echo \$?" || echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do
@@ -485,7 +483,7 @@ jobs:
         for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
-          adb shell API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || any_failures=1
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test"); echo \$?" || any_failures=1
         done
         echo "Failures: $any_failures"
         exit $any_failures
@@ -497,6 +495,7 @@ jobs:
         api-level: ${{ env.API_LEVEL }}
         arch: ${{ matrix.emulator-arch == 'arm64-v8' && 'arm64-v8a' || matrix.emulator-arch }}
         ndk: ${{ env.NDK_VERSION }}
+        emulator-boot-timeout: 120
         script: /tmp/rust-android-run-tests-on-emulator.sh
       env:
         TARGET: ${{ matrix.target }}

From 4326be0305fff882140042da2c569d4eaaf4e883 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 11:19:20 +0200
Subject: [PATCH 36/54] printf

---
 .github/workflows/check.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index cb96f9c5..6bdc4641 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -470,8 +470,8 @@ jobs:
         #!/bin/bash
         set -e
         adb shell ip addr show
-        adb shell "false; echo \$?" || echo failed false
-        adb shell "true; echo \$?" || echo failed true
+        adb shell "false; printf \$?" || echo failed false
+        adb shell "true; printf \$?" || echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do
@@ -483,7 +483,7 @@ jobs:
         for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
-          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test"); echo \$?" || any_failures=1
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test"); printf \$?" || any_failures=1
         done
         echo "Failures: $any_failures"
         exit $any_failures

From 63b165aa6aa48fd40f04f54b4dd49106a21ca2fd Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 11:24:01 +0200
Subject: [PATCH 37/54] tr

---
 .github/workflows/check.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 6bdc4641..9141e629 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -470,8 +470,8 @@ jobs:
         #!/bin/bash
         set -e
         adb shell ip addr show
-        adb shell "false; printf \$?" || echo failed false
-        adb shell "true; printf \$?" || echo failed true
+        adb shell "false; echo \$? | tr -d '\r'" || echo failed false
+        adb shell "true; echo \$? | tr -d '\r'" || echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do
@@ -483,7 +483,7 @@ jobs:
         for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
-          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test"); printf \$?" || any_failures=1
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test"); echo \$? | tr -d '\r'" || any_failures=1
         done
         echo "Failures: $any_failures"
         exit $any_failures

From 44e675312070e1757c397409ff28bae8e32e8953 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 11:35:00 +0200
Subject: [PATCH 38/54] Again

---
 .github/workflows/check.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 9141e629..96700b40 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -470,8 +470,8 @@ jobs:
         #!/bin/bash
         set -e
         adb shell ip addr show
-        adb shell "false; echo \$? | tr -d '\r'" || echo failed false
-        adb shell "true; echo \$? | tr -d '\r'" || echo failed true
+        adb shell "false && echo SUCCESS || echo FAIL" | | grep FAIL && echo failed false
+        adb shell "true && echo SUCCESS || echo FAIL" | | grep FAIL && echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do
@@ -483,7 +483,7 @@ jobs:
         for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
-          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test"); echo \$? | tr -d '\r'" || any_failures=1
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo SUCCESS || echo FAIL" | | grep FAIL && any_failures=1
         done
         echo "Failures: $any_failures"
         exit $any_failures

From 0056370ac178a5dc9fae45384fb10e38fd3c6a47 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 11:54:37 +0200
Subject: [PATCH 39/54] Again

---
 .github/workflows/check.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 96700b40..998f14ed 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -470,8 +470,8 @@ jobs:
         #!/bin/bash
         set -e
         adb shell ip addr show
-        adb shell "false && echo SUCCESS || echo FAIL" | | grep FAIL && echo failed false
-        adb shell "true && echo SUCCESS || echo FAIL" | | grep FAIL && echo failed true
+        adb shell "false && echo SUCCESS || echo FAIL" | grep FAIL && echo failed false
+        adb shell "true && echo SUCCESS || echo FAIL" | grep FAIL && echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do
@@ -483,7 +483,7 @@ jobs:
         for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
-          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo SUCCESS || echo FAIL" | | grep FAIL && any_failures=1
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo SUCCESS || echo FAIL" | grep FAIL && any_failures=1
         done
         echo "Failures: $any_failures"
         exit $any_failures

From 1e588039d714248f0f20e2776af48e7a0c1f4624 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 12:02:25 +0200
Subject: [PATCH 40/54] Test

---
 .github/workflows/check.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 998f14ed..ab14a4ef 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -470,19 +470,19 @@ jobs:
         #!/bin/bash
         set -e
         adb shell ip addr show
-        adb shell "false && echo SUCCESS || echo FAIL" | grep FAIL && echo failed false
-        adb shell "true && echo SUCCESS || echo FAIL" | grep FAIL && echo failed true
+        adb shell "false && echo \$?" | tr -d'\r' && echo failed false
+        adb shell "true && echo \$?" | tr -d'\r' && echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do
           adb devices
           sleep 1;
         done
-        echo Gogogo
         any_failures=0
         for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
+          # See
           adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo SUCCESS || echo FAIL" | grep FAIL && any_failures=1
         done
         echo "Failures: $any_failures"

From fe47c1ac91414377f197b486d2887032c2f97232 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 12:05:06 +0200
Subject: [PATCH 41/54] Again

---
 .github/workflows/check.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index ab14a4ef..af5771f9 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -470,8 +470,8 @@ jobs:
         #!/bin/bash
         set -e
         adb shell ip addr show
-        adb shell "false && echo \$?" | tr -d'\r' && echo failed false
-        adb shell "true && echo \$?" | tr -d'\r' && echo failed true
+        adb shell "false && echo \$?" | tr -d '\r' && echo failed false
+        adb shell "true && echo \$?" | tr -d '\r' && echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do

From 536820c2a36713fce3cb07c52935c098d4327f0e Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 12:17:29 +0200
Subject: [PATCH 42/54] Again

---
 .github/workflows/check.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index af5771f9..a4728686 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -470,8 +470,8 @@ jobs:
         #!/bin/bash
         set -e
         adb shell ip addr show
-        adb shell "false && echo \$?" | tr -d '\r' && echo failed false
-        adb shell "true && echo \$?" | tr -d '\r' && echo failed true
+        [ $(adb shell "false && echo \$?" | tr -d '\r') ] && echo failed false
+        [ $(adb shell "true && echo \$?" | tr -d '\r') ] && echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do
@@ -483,7 +483,7 @@ jobs:
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
           # See
-          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo SUCCESS || echo FAIL" | grep FAIL && any_failures=1
+          [ $(adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo \$?" | tr -d '\r') ] && any_failures=1
         done
         echo "Failures: $any_failures"
         exit $any_failures

From 937c7f3f32f8ce4bdc299b2387920c07245b7394 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 12:24:52 +0200
Subject: [PATCH 43/54] Again

---
 .github/workflows/check.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index a4728686..508be12a 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -470,8 +470,8 @@ jobs:
         #!/bin/bash
         set -e
         adb shell ip addr show
-        [ $(adb shell "false && echo \$?" | tr -d '\r') ] && echo failed false
-        [ $(adb shell "true && echo \$?" | tr -d '\r') ] && echo failed true
+        [ "$(adb shell "false && echo \$?" | tr -d '\r')" ] && echo failed false
+        [ "$(adb shell "true && echo \$?" | tr -d '\r')" ] && echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
         while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do
@@ -483,7 +483,7 @@ jobs:
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
           # See
-          [ $(adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo \$?" | tr -d '\r') ] && any_failures=1
+          [ "$(adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo \$?" | tr -d '\r')" ] && any_failures=1
         done
         echo "Failures: $any_failures"
         exit $any_failures

From 4d398b5a9776f75a5085fdb4973cd729a7e01873 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 12:34:36 +0200
Subject: [PATCH 44/54] Again

---
 .github/workflows/check.yml | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 508be12a..b6395b7d 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -454,11 +454,7 @@ jobs:
         tools: cargo-ndk
         token: ${{ secrets.GITHUB_TOKEN }}
 
-    - run: |
-        # FIXME: Remove resetting RUSTFLAGS once Android support for neqo has landed.
-        echo "RUSTFLAGS=''" >> "$GITHUB_ENV"
-        export RUSTFLAGS=""
-        cargo -vv ndk -t ${{ matrix.target }} test --no-run
+    - run: cargo ndk -t ${{ matrix.target }} test --no-run
 
     - env:
         TARGET: ${{ matrix.target }}
@@ -470,22 +466,16 @@ jobs:
         #!/bin/bash
         set -e
         adb shell ip addr show
-        [ "$(adb shell "false && echo \$?" | tr -d '\r')" ] && echo failed false
-        [ "$(adb shell "true && echo \$?" | tr -d '\r')" ] && echo failed true
         export GITHUB_ACTIONS=1
         adb wait-for-device
-        while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do
-          adb devices
-          sleep 1;
-        done
+        while [ -z "$(adb shell getprop sys.boot_completed | tr -d '\r')" ]; do sleep 1; done
         any_failures=0
         for test in $(find target/$TARGET/debug/deps/ -type f -executable ! -name "*.so" -name "*-*"); do
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
-          # See
-          [ "$(adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo \$?" | tr -d '\r')" ] && any_failures=1
+          # See https://unix.stackexchange.com/a/451140/409256
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo SUCCESS || echo FAIL" | grep FAIL && any_failures=1
         done
-        echo "Failures: $any_failures"
         exit $any_failures
         EOF
         chmod a+x /tmp/rust-android-run-tests-on-emulator.sh

From e4616b0836c8bea1dbabeeed667f78505d4241e7 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 13:22:16 +0200
Subject: [PATCH 45/54] Again

---
 .github/workflows/check.yml | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index b6395b7d..1ea07ad1 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -421,10 +421,11 @@ jobs:
             emulator-arch: x86_64
             # Note that x86_64 image is only available for API 21+. See
             # https://github.com/ReactiveCircus/android-emulator-runner?tab=readme-ov-file#configurations.
-          - target: armv7-linux-androideabi
-            emulator-arch: arm64-v8
           - target: i686-linux-android
             emulator-arch: x86
+          # FIXME: https://github.com/ReactiveCircus/android-emulator-runner/issues/404
+          # - target: armv7-linux-androideabi
+          #   emulator-arch: arm64-v8
 
     steps:
     - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -474,7 +475,7 @@ jobs:
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
           # See https://unix.stackexchange.com/a/451140/409256
-          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo SUCCESS || echo FAIL" | grep FAIL && any_failures=1
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo SUCCESS >&2 || echo FAIL >&2" 2>&1 | grep FAIL && any_failures=1
         done
         exit $any_failures
         EOF

From 68e03019cb3e06f2e65a76477ca6e5d28bface28 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 13:30:47 +0200
Subject: [PATCH 46/54] output

---
 .github/workflows/check.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 1ea07ad1..791e818c 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -475,7 +475,7 @@ jobs:
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
           # See https://unix.stackexchange.com/a/451140/409256
-          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") && echo SUCCESS >&2 || echo FAIL >&2" 2>&1 | grep FAIL && any_failures=1
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || echo _FAIL_" 2>&1 | grep -E -e '' -e _FAIL_ && any_failures=1
         done
         exit $any_failures
         EOF

From a86a9a1160b07ea19a6092f18e41ace17755a6b1 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 13:38:06 +0200
Subject: [PATCH 47/54] Fix test

---
 src/lib.rs | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index 7d89e629..5be8119f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -146,7 +146,7 @@ mod test {
         }
     }
 
-    #[cfg(any(target_os = "macos", target_os = "freebsd",))]
+    #[cfg(any(target_os = "macos", target_os = "freebsd"))]
     const LOOPBACK: &[NameMtu] = &[NameMtu(Some("lo0"), 16_384), NameMtu(Some("lo0"), 16_384)];
     #[cfg(any(target_os = "linux", target_os = "android"))]
     const LOOPBACK: &[NameMtu] = &[NameMtu(Some("lo"), 65_536), NameMtu(Some("lo"), 65_536)];
@@ -164,7 +164,14 @@ mod test {
     const LOOPBACK: &[NameMtu] = &[NameMtu(Some("lo0"), 8_232), NameMtu(Some("lo0"), 8_252)];
 
     // Non-loopback interface names are unpredictable, so we only check the MTU.
-    const INET: NameMtu = NameMtu(None, 1_500);
+    const INET: NameMtu = NameMtu(
+        None,
+        if cfg!(target_os = "android") {
+            1_440 // At least inside the Android emulator we use in CI.
+        } else {
+            1_500
+        },
+    );
 
     #[test]
     fn loopback_v4() {

From 3ef465fc392528a729257fe93029737d9418d102 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 13:42:37 +0200
Subject: [PATCH 48/54] Debug

---
 .github/workflows/check.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 791e818c..bfc1f358 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -475,8 +475,11 @@ jobs:
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
           # See https://unix.stackexchange.com/a/451140/409256
+          echo before $any_failures
           adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || echo _FAIL_" 2>&1 | grep -E -e '' -e _FAIL_ && any_failures=1
+          echo after $any_failures
         done
+        echo end $any_failures
         exit $any_failures
         EOF
         chmod a+x /tmp/rust-android-run-tests-on-emulator.sh

From c686cc6625635c1f48782becff6898fb674d6471 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 13:56:41 +0200
Subject: [PATCH 49/54] test

---
 .github/workflows/check.yml |  2 +-
 src/lib.rs                  | 38 ++++++++++++++++++++-----------------
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index bfc1f358..1dd3b142 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -476,7 +476,7 @@ jobs:
           adb shell chmod +x /data/local/tmp/$(basename "$test")
           # See https://unix.stackexchange.com/a/451140/409256
           echo before $any_failures
-          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || echo _FAIL_" 2>&1 | grep -E -e '' -e _FAIL_ && any_failures=1
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || echo _FAIL_" 2>&1 | grep -E -e '' -e _FAIL_ || any_failures=1
           echo after $any_failures
         done
         echo end $any_failures
diff --git a/src/lib.rs b/src/lib.rs
index 5be8119f..f0f66235 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -146,28 +146,32 @@ mod test {
         }
     }
 
-    #[cfg(any(target_os = "macos", target_os = "freebsd"))]
-    const LOOPBACK: &[NameMtu] = &[NameMtu(Some("lo0"), 16_384), NameMtu(Some("lo0"), 16_384)];
-    #[cfg(any(target_os = "linux", target_os = "android"))]
-    const LOOPBACK: &[NameMtu] = &[NameMtu(Some("lo"), 65_536), NameMtu(Some("lo"), 65_536)];
-    #[cfg(target_os = "windows")]
-    const LOOPBACK: &[NameMtu] = &[
-        NameMtu(Some("loopback_0"), 4_294_967_295),
-        NameMtu(Some("loopback_0"), 4_294_967_295),
-    ];
-    #[cfg(target_os = "openbsd")]
-    const LOOPBACK: &[NameMtu] = &[NameMtu(Some("lo0"), 32_768), NameMtu(Some("lo0"), 32_768)];
-    #[cfg(target_os = "netbsd")]
-    const LOOPBACK: &[NameMtu] = &[NameMtu(Some("lo0"), 33_624), NameMtu(Some("lo0"), 33_624)];
-    #[cfg(target_os = "solaris")]
-    // Note: Different loopback MTUs for IPv4 and IPv6?!
-    const LOOPBACK: &[NameMtu] = &[NameMtu(Some("lo0"), 8_232), NameMtu(Some("lo0"), 8_252)];
+    const LOOPBACK: [NameMtu; 2] = // [IPv4, IPv6]
+        if cfg!(any(target_os = "macos", target_os = "freebsd")) {
+            [NameMtu(Some("lo0"), 16_384), NameMtu(Some("lo0"), 16_384)]
+        } else if cfg!(any(target_os = "linux", target_os = "android")) {
+            [NameMtu(Some("lo"), 65_536), NameMtu(Some("lo"), 65_536)]
+        } else if cfg!(target_os = "windows") {
+            [
+                NameMtu(Some("loopback_0"), 4_294_967_295),
+                NameMtu(Some("loopback_0"), 4_294_967_295),
+            ]
+        } else if cfg!(target_os = "openbsd") {
+            [NameMtu(Some("lo0"), 32_768), NameMtu(Some("lo0"), 32_768)]
+        } else if cfg!(target_os = "netbsd") {
+            [NameMtu(Some("lo0"), 33_624), NameMtu(Some("lo0"), 33_624)]
+        } else if cfg!(target_os = "solaris") {
+            // Note: Different loopback MTUs for IPv4 and IPv6?!
+            [NameMtu(Some("lo0"), 8_232), NameMtu(Some("lo0"), 8_252)]
+        } else {
+            unreachable!();
+        };
 
     // Non-loopback interface names are unpredictable, so we only check the MTU.
     const INET: NameMtu = NameMtu(
         None,
         if cfg!(target_os = "android") {
-            1_440 // At least inside the Android emulator we use in CI.
+            1_441 // At least inside the Android emulator we use in CI.
         } else {
             1_500
         },

From 76d56c2009c78a20512cabd6842ee097e8abf406 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 14:02:22 +0200
Subject: [PATCH 50/54] condition

---
 .github/workflows/check.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 1dd3b142..ceec6a99 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -476,7 +476,7 @@ jobs:
           adb shell chmod +x /data/local/tmp/$(basename "$test")
           # See https://unix.stackexchange.com/a/451140/409256
           echo before $any_failures
-          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || echo _FAIL_" 2>&1 | grep -E -e '' -e _FAIL_ || any_failures=1
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || echo _FAIL_" 2>&1 | cat - | grep _FAIL_ && any_failures=1
           echo after $any_failures
         done
         echo end $any_failures

From 7219addc6b4faccab72f93e72c302cb968df811d Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 14:10:55 +0200
Subject: [PATCH 51/54] Again

---
 .github/workflows/check.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index ceec6a99..789bba76 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -476,7 +476,8 @@ jobs:
           adb shell chmod +x /data/local/tmp/$(basename "$test")
           # See https://unix.stackexchange.com/a/451140/409256
           echo before $any_failures
-          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || echo _FAIL_" 2>&1 | cat - | grep _FAIL_ && any_failures=1
+          adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || echo _FAIL_" 2>&1 | tee output
+          grep _FAIL_ output && any_failures=1
           echo after $any_failures
         done
         echo end $any_failures

From 5b86b45024236afb3b8966a107f46871367572c1 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 14:14:21 +0200
Subject: [PATCH 52/54] Fix

---
 src/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lib.rs b/src/lib.rs
index f0f66235..1f540ad0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -171,7 +171,7 @@ mod test {
     const INET: NameMtu = NameMtu(
         None,
         if cfg!(target_os = "android") {
-            1_441 // At least inside the Android emulator we use in CI.
+            1_440 // At least inside the Android emulator we use in CI.
         } else {
             1_500
         },

From f7fb2b324655b53ec1517dc5543186a234a8d630 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Wed, 5 Mar 2025 14:18:07 +0200
Subject: [PATCH 53/54] Finalize

---
 .github/workflows/check.yml | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 789bba76..b1ff5afb 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -475,12 +475,9 @@ jobs:
           adb push "$test" /data/local/tmp/
           adb shell chmod +x /data/local/tmp/$(basename "$test")
           # See https://unix.stackexchange.com/a/451140/409256
-          echo before $any_failures
           adb shell "API_LEVEL=$API_LEVEL /data/local/tmp/$(basename "$test") || echo _FAIL_" 2>&1 | tee output
           grep _FAIL_ output && any_failures=1
-          echo after $any_failures
         done
-        echo end $any_failures
         exit $any_failures
         EOF
         chmod a+x /tmp/rust-android-run-tests-on-emulator.sh

From 2fffd9bd472c72b70c239417116f8b95d2c8c710 Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Mon, 10 Mar 2025 14:06:34 +0200
Subject: [PATCH 54/54] MSRV

---
 Cargo.toml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Cargo.toml b/Cargo.toml
index 268c27e9..fc2a12c6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -77,7 +77,7 @@ infinite_loop = "warn"
 large_include_file = "warn"
 let_underscore_must_use = "warn"
 let_underscore_untyped = "warn"
-literal_string_with_formatting_args = "allow" # FIXME: Re-enable "warn" when MRSV is > 1.87. See https://github.com/rust-lang/rust-clippy/pull/13953#issuecomment-2676336899
+literal_string_with_formatting_args = "allow" # FIXME: Re-enable "warn" when MSRV is > 1.87. See https://github.com/rust-lang/rust-clippy/pull/13953#issuecomment-2676336899
 lossy_float_literal = "warn"
 mem_forget = "warn"
 mixed_read_write_in_expression = "warn"
