android fixes
This commit is contained in:
parent
ffe0a42dd3
commit
e412e47474
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -13,3 +13,6 @@
|
|||||||
[submodule "external/keyvaluedb"]
|
[submodule "external/keyvaluedb"]
|
||||||
path = external/keyvaluedb
|
path = external/keyvaluedb
|
||||||
url = ../keyvaluedb.git
|
url = ../keyvaluedb.git
|
||||||
|
[submodule "external/netlink"]
|
||||||
|
path = external/netlink
|
||||||
|
url = git@gitlab.hackers.town:veilid/netlink.git
|
||||||
|
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -2126,8 +2126,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "netlink-packet-core"
|
name = "netlink-packet-core"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8349128e95f5dabcb8a18587ad06b3ca7993e90c0c360b4a2abac0313ebce727"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@ -2138,8 +2136,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "netlink-packet-route"
|
name = "netlink-packet-route"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9fb5d54077de7c0904111e1d19b661b8cfccbc23d9ce5b6dbcc7362721e6e552"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
@ -2152,8 +2148,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "netlink-packet-utils"
|
name = "netlink-packet-utils"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0a008a56eceb0cab06739c7f37f15bda27f1147a14d0e7136e8c913b94f1441d"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@ -2164,8 +2158,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "netlink-proto"
|
name = "netlink-proto"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "073885f70c1d54fdc6148075e8e38a5e8a28179f59de5bd0fc6277cae4fec95a"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 1.1.0",
|
"bytes 1.1.0",
|
||||||
"futures",
|
"futures",
|
||||||
@ -2178,8 +2170,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "netlink-sys"
|
name = "netlink-sys"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ed51a4602bb956eefef0ebc15f478bf9732fa3cc706e0a37112e654f41c5b92c"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-io",
|
"async-io",
|
||||||
"bytes 1.1.0",
|
"bytes 1.1.0",
|
||||||
@ -2938,8 +2928,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rtnetlink"
|
name = "rtnetlink"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fa584f57f271d3fbd9f59503b090a0410a531c8cc272143669bf136c62ef409d"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-global-executor",
|
"async-global-executor",
|
||||||
"futures",
|
"futures",
|
||||||
|
13
Cargo.toml
13
Cargo.toml
@ -12,6 +12,19 @@ exclude = [ "./external/cursive" ]
|
|||||||
cursive = { path = "./external/cursive/cursive" }
|
cursive = { path = "./external/cursive/cursive" }
|
||||||
cursive_core = { path = "./external/cursive/cursive-core" }
|
cursive_core = { path = "./external/cursive/cursive-core" }
|
||||||
|
|
||||||
|
netlink-sys = { path = "./external/netlink/netlink-sys" }
|
||||||
|
netlink-packet-core = { path = "./external/netlink/netlink-packet-core" }
|
||||||
|
netlink-packet-utils = { path = "./external/netlink/netlink-packet-utils" }
|
||||||
|
#netlink-packet-generic = { path = "./external/netlink/netlink-packet-generic" }
|
||||||
|
netlink-packet-route = { path = "./external/netlink/netlink-packet-route" }
|
||||||
|
#netlink-packet-audit = { path = "./external/netlink/netlink-packet-audit" }
|
||||||
|
#netlink-packet-sock-diag = { path = "./external/netlink/netlink-packet-sock-diag" }
|
||||||
|
netlink-proto = { path = "./external/netlink/netlink-proto" }
|
||||||
|
#genetlink = { path = "./external/netlink/genetlink" }
|
||||||
|
rtnetlink = { path = "./external/netlink/rtnetlink" }
|
||||||
|
#audit = { path = "./external/netlink/audit" }
|
||||||
|
#ethtool = { path = "./external/netlink/ethtool" }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = "s"
|
opt-level = "s"
|
||||||
lto = true
|
lto = true
|
||||||
|
1
external/netlink
vendored
Submodule
1
external/netlink
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit bf542d210ec3c3f1c359b49036dc938ddfb3fdf9
|
@ -79,8 +79,10 @@ pub struct InterfaceFlags {
|
|||||||
/// Some of the flags associated with an address.
|
/// Some of the flags associated with an address.
|
||||||
#[derive(Debug, Default, PartialEq, Eq, Ord, PartialOrd, Hash, Clone, Copy)]
|
#[derive(Debug, Default, PartialEq, Eq, Ord, PartialOrd, Hash, Clone, Copy)]
|
||||||
pub struct AddressFlags {
|
pub struct AddressFlags {
|
||||||
pub is_temporary: bool,
|
// common flags
|
||||||
pub is_dynamic: bool,
|
pub is_dynamic: bool,
|
||||||
|
// ipv6 flags
|
||||||
|
pub is_temporary: bool,
|
||||||
pub is_deprecated: bool,
|
pub is_deprecated: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +92,84 @@ pub struct InterfaceAddress {
|
|||||||
flags: AddressFlags,
|
flags: AddressFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
|
impl Ord for InterfaceAddress {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
match (&self.if_addr, &other.if_addr) {
|
||||||
|
(IfAddr::V4(a), IfAddr::V4(b)) => {
|
||||||
|
// global scope addresses are better
|
||||||
|
let ret = ipv4addr_is_global(&a.ip).cmp(&ipv4addr_is_global(&b.ip));
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// local scope addresses are better
|
||||||
|
let ret = ipv4addr_is_private(&a.ip).cmp(&ipv4addr_is_private(&b.ip));
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// non-dynamic addresses are better
|
||||||
|
let ret = (!self.flags.is_dynamic).cmp(&!other.flags.is_dynamic);
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(IfAddr::V6(a), IfAddr::V6(b)) => {
|
||||||
|
// non-deprecated addresses are better
|
||||||
|
let ret = (!self.flags.is_deprecated).cmp(&!other.flags.is_deprecated);
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// non-temporary address are better
|
||||||
|
let ret = (!self.flags.is_temporary).cmp(&!other.flags.is_temporary);
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// global scope addresses are better
|
||||||
|
let ret = ipv6addr_is_global(&a.ip).cmp(&ipv6addr_is_global(&b.ip));
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// unique local unicast addresses are better
|
||||||
|
let ret = ipv6addr_is_unique_local(&a.ip).cmp(&ipv6addr_is_unique_local(&b.ip));
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// unicast site local addresses are better
|
||||||
|
let ret = ipv6addr_is_unicast_site_local(&a.ip)
|
||||||
|
.cmp(&ipv6addr_is_unicast_site_local(&b.ip));
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// unicast link local addresses are better
|
||||||
|
let ret = ipv6addr_is_unicast_link_local(&a.ip)
|
||||||
|
.cmp(&ipv6addr_is_unicast_link_local(&b.ip));
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// non-dynamic addresses are better
|
||||||
|
let ret = (!self.flags.is_dynamic).cmp(&!other.flags.is_dynamic);
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(IfAddr::V4(_), IfAddr::V6(_)) => return Ordering::Less,
|
||||||
|
(IfAddr::V6(_), IfAddr::V4(_)) => return Ordering::Greater,
|
||||||
|
}
|
||||||
|
// stable sort
|
||||||
|
let ret = self.if_addr.cmp(&other.if_addr);
|
||||||
|
if ret != Ordering::Equal {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
self.flags.cmp(&other.flags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PartialOrd for InterfaceAddress {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl InterfaceAddress {
|
impl InterfaceAddress {
|
||||||
pub fn new(if_addr: IfAddr, flags: AddressFlags) -> Self {
|
pub fn new(if_addr: IfAddr, flags: AddressFlags) -> Self {
|
||||||
@ -158,33 +238,35 @@ impl NetworkInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn primary_ipv4(&self) -> Option<Ipv4Addr> {
|
pub fn primary_ipv4(&self) -> Option<Ipv4Addr> {
|
||||||
// see if we have a non-dynamic address to use first
|
let mut ipv4addrs: Vec<&InterfaceAddress> = self
|
||||||
let mut best_dynamic: Option<Ipv4Addr> = None;
|
.addrs
|
||||||
for x in self.addrs.iter() {
|
.iter()
|
||||||
if let IfAddr::V4(a) = x.if_addr() {
|
.filter(|a| matches!(a.if_addr(), IfAddr::V4(_)))
|
||||||
if !x.is_dynamic() {
|
.collect();
|
||||||
return Some(a.ip);
|
ipv4addrs.sort();
|
||||||
} else if best_dynamic.is_none() {
|
ipv4addrs
|
||||||
best_dynamic = Some(a.ip);
|
.last()
|
||||||
}
|
.map(|x| match x.if_addr() {
|
||||||
}
|
IfAddr::V4(v4) => Some(v4.ip),
|
||||||
}
|
_ => None,
|
||||||
best_dynamic
|
})
|
||||||
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primary_ipv6(&self) -> Option<Ipv6Addr> {
|
pub fn primary_ipv6(&self) -> Option<Ipv6Addr> {
|
||||||
let mut best_dynamic: Option<Ipv6Addr> = None;
|
let mut ipv6addrs: Vec<&InterfaceAddress> = self
|
||||||
for x in self.addrs.iter() {
|
.addrs
|
||||||
if let IfAddr::V6(a) = x.if_addr() {
|
.iter()
|
||||||
if x.is_temporary() || x.is_deprecated() {
|
.filter(|a| matches!(a.if_addr(), IfAddr::V6(_)))
|
||||||
if !x.is_dynamic() {
|
.collect();
|
||||||
return Some(a.ip);
|
ipv6addrs.sort();
|
||||||
} else if best_dynamic.is_none() {
|
ipv6addrs
|
||||||
best_dynamic = Some(a.ip);
|
.last()
|
||||||
}
|
.map(|x| match x.if_addr() {
|
||||||
}
|
IfAddr::V6(v6) => Some(v6.ip),
|
||||||
}
|
_ => None,
|
||||||
}
|
})
|
||||||
best_dynamic
|
.flatten()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,11 +4,13 @@ use alloc::collections::btree_map::Entry;
|
|||||||
use futures_util::stream::TryStreamExt;
|
use futures_util::stream::TryStreamExt;
|
||||||
use ifstructs::ifreq;
|
use ifstructs::ifreq;
|
||||||
use libc::{
|
use libc::{
|
||||||
close, if_indextoname, ioctl, socket, IFA_F_DADFAILED, IFA_F_DEPRECATED, IFA_F_PERMANENT,
|
close, if_indextoname, ioctl, socket, IFF_LOOPBACK, IFF_RUNNING, IF_NAMESIZE, SIOCGIFFLAGS,
|
||||||
IFA_F_TEMPORARY, IFA_F_TENTATIVE, IFF_LOOPBACK, IFF_RUNNING, IF_NAMESIZE, SIOCGIFFLAGS,
|
|
||||||
SOCK_DGRAM,
|
SOCK_DGRAM,
|
||||||
};
|
};
|
||||||
use rtnetlink::packet::{nlas::address::Nla, AddressMessage, AF_INET, AF_INET6};
|
use rtnetlink::packet::{
|
||||||
|
nlas::address::Nla, AddressMessage, AF_INET, AF_INET6, IFA_F_DADFAILED, IFA_F_DEPRECATED,
|
||||||
|
IFA_F_PERMANENT, IFA_F_TEMPORARY, IFA_F_TENTATIVE,
|
||||||
|
};
|
||||||
use rtnetlink::{new_connection_with_socket, sys::SmolSocket, Handle, IpVersion};
|
use rtnetlink::{new_connection_with_socket, sys::SmolSocket, Handle, IpVersion};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
@ -18,9 +20,18 @@ use tools::*;
|
|||||||
|
|
||||||
fn get_interface_name(index: u32) -> Result<String, String> {
|
fn get_interface_name(index: u32) -> Result<String, String> {
|
||||||
let mut ifnamebuf = [0u8; (IF_NAMESIZE + 1)];
|
let mut ifnamebuf = [0u8; (IF_NAMESIZE + 1)];
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(all(target_os = "android", target_arch = "aarch64"))] {
|
||||||
|
if unsafe { if_indextoname(index, ifnamebuf.as_mut_ptr()) }.is_null() {
|
||||||
|
return Err("if_indextoname returned null".to_owned());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if unsafe { if_indextoname(index, ifnamebuf.as_mut_ptr() as *mut i8) }.is_null() {
|
if unsafe { if_indextoname(index, ifnamebuf.as_mut_ptr() as *mut i8) }.is_null() {
|
||||||
return Err("if_indextoname returned null".to_owned());
|
return Err("if_indextoname returned null".to_owned());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ifnamebuflen = ifnamebuf
|
let ifnamebuflen = ifnamebuf
|
||||||
.iter()
|
.iter()
|
||||||
.position(|c| *c == 0u8)
|
.position(|c| *c == 0u8)
|
||||||
@ -95,7 +106,13 @@ impl PlatformSupportNetlink {
|
|||||||
return Err(io::Error::last_os_error()).map_err(map_to_string);
|
return Err(io::Error::last_os_error()).map_err(map_to_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(target_os = "android")] {
|
||||||
|
let res = unsafe { ioctl(sock, SIOCGIFFLAGS as i32, &mut req) };
|
||||||
|
} else {
|
||||||
let res = unsafe { ioctl(sock, SIOCGIFFLAGS, &mut req) };
|
let res = unsafe { ioctl(sock, SIOCGIFFLAGS, &mut req) };
|
||||||
|
}
|
||||||
|
}
|
||||||
unsafe { close(sock) };
|
unsafe { close(sock) };
|
||||||
if res < 0 {
|
if res < 0 {
|
||||||
return Err(io::Error::last_os_error()).map_err(map_to_string);
|
return Err(io::Error::last_os_error()).map_err(map_to_string);
|
||||||
|
Loading…
Reference in New Issue
Block a user