mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
feat(android): set search-domain on VPN configuration (#8436)
On Android, we can use [`addSearchDomain`](https://developer.android.com/reference/android/net/VpnService.Builder#addSearchDomain(java.lang.String)) to configure the search domain list for our VPN tunnel. Thankfully, this gets applied to the system resolver without any other hackery involved (unlike for Apple in #8421), and most apps use the system resolver for queries. The one exception to this are some network utilities like AndroDNS and Fing. Tested to work fine in Termux using `github.io` as the search domain, which responds to ICMP echoes to any subdomain: <img width="420" alt="Screenshot 2025-03-13 at 10 19 41 PM" src="https://github.com/user-attachments/assets/e156e644-08a8-4ab6-b49a-91ef92aabafd" /> Related #8410 --------- Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
This commit is contained in:
@@ -58,6 +58,7 @@ class TunnelService : VpnService() {
|
||||
var tunnelIpv4Address: String? = null
|
||||
var tunnelIpv6Address: String? = null
|
||||
private var tunnelDnsAddresses: MutableList<String> = mutableListOf()
|
||||
private var tunnelSearchDomain: String? = null
|
||||
private var tunnelRoutes: MutableList<Cidr> = mutableListOf()
|
||||
private var _tunnelResources: List<Resource> = emptyList()
|
||||
private var _tunnelState: State = State.DOWN
|
||||
@@ -116,6 +117,7 @@ class TunnelService : VpnService() {
|
||||
addressIPv4: String,
|
||||
addressIPv6: String,
|
||||
dnsAddresses: String,
|
||||
searchDomain: String?,
|
||||
routes4JSON: String,
|
||||
routes6JSON: String,
|
||||
) {
|
||||
@@ -124,6 +126,7 @@ class TunnelService : VpnService() {
|
||||
val routes4 = moshi.adapter<MutableList<Cidr>>().fromJson(routes4JSON)!!
|
||||
val routes6 = moshi.adapter<MutableList<Cidr>>().fromJson(routes6JSON)!!
|
||||
|
||||
tunnelSearchDomain = searchDomain
|
||||
tunnelIpv4Address = addressIPv4
|
||||
tunnelIpv6Address = addressIPv6
|
||||
tunnelRoutes.clear()
|
||||
@@ -207,6 +210,10 @@ class TunnelService : VpnService() {
|
||||
addDnsServer(dns)
|
||||
}
|
||||
|
||||
tunnelSearchDomain?.let {
|
||||
addSearchDomain(it)
|
||||
}
|
||||
|
||||
addAddress(tunnelIpv4Address!!, 32)
|
||||
addAddress(tunnelIpv6Address!!, 128)
|
||||
}.establish()
|
||||
|
||||
@@ -6,6 +6,7 @@ interface ConnlibCallback {
|
||||
addressIPv4: String,
|
||||
addressIPv6: String,
|
||||
dnsAddresses: String,
|
||||
searchDomain: String?,
|
||||
routes4JSON: String,
|
||||
routes6JSON: String,
|
||||
)
|
||||
|
||||
@@ -171,7 +171,7 @@ impl Callbacks for CallbackHandler {
|
||||
tunnel_address_v4: Ipv4Addr,
|
||||
tunnel_address_v6: Ipv6Addr,
|
||||
dns_addresses: Vec<IpAddr>,
|
||||
_search_domain: Option<DomainName>,
|
||||
search_domain: Option<DomainName>,
|
||||
route_list_4: Vec<Ipv4Network>,
|
||||
route_list_6: Vec<Ipv6Network>,
|
||||
) {
|
||||
@@ -194,6 +194,16 @@ impl Callbacks for CallbackHandler {
|
||||
name: "dns_addresses",
|
||||
source,
|
||||
})?;
|
||||
let search_domain = search_domain
|
||||
.map(|domain| {
|
||||
env.new_string(domain.to_string())
|
||||
.map_err(|source| CallbackError::NewStringFailed {
|
||||
name: "search_domain",
|
||||
source,
|
||||
})
|
||||
})
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
let route_list_4 = env
|
||||
.new_string(serde_json::to_string(&V4RouteList::new(route_list_4))?)
|
||||
.map_err(|source| CallbackError::NewStringFailed {
|
||||
@@ -211,11 +221,12 @@ impl Callbacks for CallbackHandler {
|
||||
env.call_method(
|
||||
&self.callback_handler,
|
||||
name,
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
|
||||
&[
|
||||
JValue::from(&tunnel_address_v4),
|
||||
JValue::from(&tunnel_address_v6),
|
||||
JValue::from(&dns_addresses),
|
||||
JValue::from(&search_domain),
|
||||
JValue::from(&route_list_4),
|
||||
JValue::from(&route_list_6),
|
||||
],
|
||||
@@ -566,3 +577,13 @@ fn install_rustls_crypto_provider() {
|
||||
tracing::debug!("Skipping install of crypto provider because we already have one.");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn default_jstring_is_null() {
|
||||
assert!(JString::default().is_null())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user