Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ jobs:
- name: Install cargo-ndk
run: cargo install --version 4.1.2 cargo-ndk

# cargo-apk is used by the NativeActivity smoke test under
# iroh-dns/tests/android_apk/. Only x86_64-linux-android runs the
# emulator, but installing it on every Android matrix entry is
# cheap with cargo-binstall.
- name: Install cargo-binstall
if: matrix.target == 'x86_64-linux-android'
uses: cargo-bins/cargo-binstall@main

- name: Install cargo-apk
if: matrix.target == 'x86_64-linux-android'
run: cargo binstall --no-confirm cargo-apk

# Replace cargo-ndk-runner with a wrapper that forwards RUST_LOG
# and RUST_BACKTRACE into the emulator shell. The upstream binary
# does `adb shell <bin>` without inheriting any host env.
Expand Down Expand Up @@ -220,6 +232,16 @@ jobs:
cargo ndk test -p iroh-dns --features tls-ring
cargo ndk test -p iroh-relay --features tls-ring,metrics
cargo ndk test -p iroh --features tls-ring,metrics,portmapper,test-utils
# APK smoke test: a real NativeActivity exercises the JNI path
# against the emulator's ConnectivityService. cargo-apk does not
# propagate the in-app exit code, so poll logcat for `RESULT=ok`.
# `android-emulator-runner` runs each line in its own `sh -c`,
# so multi-line constructs have to stay on one line.
adb logcat -c
(cd iroh-dns/tests/android_apk && cargo apk run --no-logcat --target $CARGO_NDK_TARGET)
for _ in $(seq 1 60); do adb logcat -d -v raw | grep -qF 'RESULT=ok' && break || sleep 1; done
adb logcat -d -v raw | grep -qF 'RESULT=ok' || { echo "iroh-dns-android-test: timed out waiting for RESULT=ok" >&2; adb logcat -d | grep -E 'iroh_dns_smoke|net.iroh.dns.test|FATAL|AndroidRuntime' | tail -100; exit 1; }
echo "iroh-dns-android-test: ok"

cross_test:
name: Cross Test
Expand Down
38 changes: 25 additions & 13 deletions iroh-dns/src/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,40 @@
//! [`ndk_context`]: https://docs.rs/ndk-context

use std::ffi::c_void;
#[cfg(debug_assertions)]
use std::panic::{AssertUnwindSafe, catch_unwind};

use hickory_resolver::{
config::{ResolverConfig, ResolverOpts},
net::NetError,
};
use tracing::debug;

/// Reads the active network's DNS configuration via JNI.
pub(crate) fn read_system_conf() -> Result<(ResolverConfig, ResolverOpts), NetError> {
#[cfg(debug_assertions)]
{
use std::panic::{AssertUnwindSafe, catch_unwind};
match catch_unwind(AssertUnwindSafe(
hickory_resolver::system_conf::read_system_conf,
)) {
Ok(Ok(conf)) => Ok(conf),
Ok(Err(err)) => Err(NetError::from(err)),
Err(_) => Err(NetError::Msg(
"ndk_context not initialized; call install_android_jni_context".to_string(),
)),
}
let (config, options) = read_inner()?;
debug!(
nameserver_count = config.name_servers().len(),
"read system DNS via Android JNI",
);
Ok((config, options))
}

#[cfg(debug_assertions)]
fn read_inner() -> Result<(ResolverConfig, ResolverOpts), NetError> {
match catch_unwind(AssertUnwindSafe(
hickory_resolver::system_conf::read_system_conf,
)) {
Ok(Ok(conf)) => Ok(conf),
Ok(Err(err)) => Err(NetError::from(err)),
Err(_) => Err(NetError::Msg(
"ndk_context not initialized; call install_android_jni_context".to_string(),
)),
}
#[cfg(not(debug_assertions))]
}

#[cfg(not(debug_assertions))]
fn read_inner() -> Result<(ResolverConfig, ResolverOpts), NetError> {
Ok(hickory_resolver::system_conf::read_system_conf()?)
}

Expand Down
1 change: 1 addition & 0 deletions iroh-dns/tests/android_apk/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
Loading
Loading