Slim down a little, test getifaddrs.

This commit is contained in:
Adam Ierymenko 2021-02-22 16:00:56 -05:00
parent d201cdec2a
commit 80e2740a89
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
4 changed files with 75 additions and 95 deletions

View file

@ -472,15 +472,6 @@ dependencies = [
"bytes",
]
[[package]]
name = "instant"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "itoa"
version = "0.4.7"
@ -499,15 +490,6 @@ version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
[[package]]
name = "lock_api"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.13"
@ -653,31 +635,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "parking_lot"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
dependencies = [
"instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272"
dependencies = [
"cfg-if 1.0.0",
"instant",
"libc",
"redox_syscall 0.1.57",
"smallvec",
"winapi",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"
@ -859,12 +816,6 @@ dependencies = [
"rand_core 0.6.1",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_syscall"
version = "0.2.4"
@ -901,12 +852,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.119"
@ -990,12 +935,6 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "smallvec"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
[[package]]
name = "socket2"
version = "0.3.19"
@ -1033,7 +972,7 @@ dependencies = [
"cfg-if 1.0.0",
"libc",
"rand 0.8.2",
"redox_syscall 0.2.4",
"redox_syscall",
"remove_dir_all",
"winapi",
]
@ -1094,9 +1033,7 @@ dependencies = [
"libc",
"memchr",
"mio",
"num_cpus",
"once_cell",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"tokio-macros",
@ -1105,9 +1042,9 @@ dependencies = [
[[package]]
name = "tokio-macros"
version = "1.0.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42517d2975ca3114b22a16192634e8241dc5cc1f130be194645970cc1c371494"
checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57"
dependencies = [
"proc-macro2",
"quote",

View file

@ -10,7 +10,7 @@ build = "build.rs"
[dependencies]
zerotier-core = { path = "../rust-zerotier-core" }
num_cpus = "1"
tokio = { version = "1", features = ["full"] }
tokio = { version = "1", features = ["rt", "net", "time", "signal", "macros"] }
warp = "0"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

View file

@ -11,7 +11,6 @@
*/
/****/
use std::ffi::CStr;
use std::mem::size_of;
use std::ptr::{copy_nonoverlapping, null_mut};
@ -30,6 +29,7 @@ fn s6_addr_as_ptr<A>(a: &A) -> *const A {
#[cfg(unix)]
pub(crate) fn for_each_address<F: FnMut(&InetAddress, &str)>(mut f: F) {
unsafe {
let mut ifa_name = [0_u8; osdep::IFNAMSIZ as usize];
let mut ifap: *mut osdep::ifaddrs = null_mut();
if osdep::getifaddrs((&mut ifap as *mut *mut osdep::ifaddrs).cast()) == 0 {
let mut i = ifap;
@ -43,6 +43,7 @@ pub(crate) fn for_each_address<F: FnMut(&InetAddress, &str)>(mut f: F) {
} else if sa_family == osdep::AF_INET6 as u8 {
copy_nonoverlapping((*i).ifa_addr.cast::<u8>(), (&mut a as *mut InetAddress).cast::<u8>(), size_of::<osdep::sockaddr_in6>());
} else {
i = (*i).ifa_next;
continue;
}
@ -66,9 +67,21 @@ pub(crate) fn for_each_address<F: FnMut(&InetAddress, &str)>(mut f: F) {
}
a.set_port(netmask_bits);
let dev = CStr::from_ptr((*i).ifa_name).to_str();
if dev.is_ok() {
f(&a, dev.unwrap());
let mut namlen: usize = 0;
while namlen < (osdep::IFNAMSIZ as usize) {
let c = *(*i).ifa_name.offset(namlen as isize);
if c != 0 {
ifa_name[namlen] = c as u8;
namlen += 1;
} else {
break;
}
}
if namlen > 0 {
let dev = String::from_utf8_lossy(&ifa_name[0..namlen]);
if dev.len() > 0 {
f(&a, dev.as_ref());
}
}
}
i = (*i).ifa_next;
@ -77,3 +90,17 @@ pub(crate) fn for_each_address<F: FnMut(&InetAddress, &str)>(mut f: F) {
}
}
}
#[cfg(test)]
mod tests {
use zerotier_core::InetAddress;
#[test]
fn test_getifaddrs() {
println!("starting getifaddrs...");
crate::getifaddrs::for_each_address(|a: &InetAddress, dev: &str| {
println!(" device: {} ip: {}", dev, a.to_string())
});
println!("done.")
}
}

View file

@ -12,7 +12,7 @@
/****/
use std::collections::BTreeMap;
use std::net::IpAddr;
use std::net::{IpAddr, SocketAddr};
use std::str::FromStr;
use std::sync::{Arc, Mutex, Weak};
use std::sync::atomic::{AtomicBool, Ordering};
@ -66,6 +66,10 @@ impl NodeEventHandler<Network> for Service {
Event::Trace => {
if !event_data.is_empty() {
let _ = Dictionary::new_from_bytes(event_data).map(|tm| {
let tm = zerotier_core::trace::TraceEvent::parse_message(&tm);
let _ = tm.map(|tm| {
self.log.log(tm.to_string());
});
});
}
}
@ -110,17 +114,17 @@ impl NodeEventHandler<Network> for Service {
impl Service {
#[inline(always)]
fn web_api_status(&self, method: Method, headers: HeaderMap, post_data: Bytes) -> Box<dyn Reply> {
fn web_api_status(&self, remote: Option<SocketAddr>, method: Method, headers: HeaderMap, post_data: Bytes) -> Box<dyn Reply> {
Box::new(StatusCode::BAD_REQUEST)
}
#[inline(always)]
fn web_api_network(&self, network_str: String, method: Method, headers: HeaderMap, post_data: Bytes) -> Box<dyn Reply> {
fn web_api_network(&self, network_str: String, remote: Option<SocketAddr>, method: Method, headers: HeaderMap, post_data: Bytes) -> Box<dyn Reply> {
Box::new(StatusCode::BAD_REQUEST)
}
#[inline(always)]
fn web_api_peer(&self, peer_str: String, method: Method, headers: HeaderMap, post_data: Bytes) -> Box<dyn Reply> {
fn web_api_peer(&self, peer_str: String, remote: Option<SocketAddr>, method: Method, headers: HeaderMap, post_data: Bytes) -> Box<dyn Reply> {
Box::new(StatusCode::BAD_REQUEST)
}
@ -204,6 +208,9 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
service.node = Arc::downgrade(&node);
let service = service; // make immutable after setting node
// The outer loop runs for as long as the service runs. It repeatedly restarts
// the inner loop, which can exit if it needs to be restarted. This is the case
// if a major configuration change occurs.
let mut loop_delay = zerotier_core::NODE_BACKGROUND_TASKS_MAX_INTERVAL;
loop {
let mut local_config = service.local_config();
@ -214,26 +221,31 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
let s0 = service.clone();
let s1 = service.clone();
let s2 = service.clone();
warp_server = warp::serve(
warp::any().and(warp::path::end().map(|| {
warp::reply::with_status("404", StatusCode::NOT_FOUND)
})
.or(warp::path("status").and(warp::method()).and(warp::header::headers_cloned()).and(warp::body::bytes())
.map(move |method: Method, headers: HeaderMap, post_data: Bytes| {
s0.web_api_status(method, headers, post_data)
}))
.or(warp::path!("network" / String).and(warp::method()).and(warp::header::headers_cloned()).and(warp::body::bytes())
.map(move |network_str: String, method: Method, headers: HeaderMap, post_data: Bytes| {
s1.web_api_network(network_str, method, headers, post_data)
}))
.or(warp::path!("peer" / String).and(warp::method()).and(warp::header::headers_cloned()).and(warp::body::bytes())
.map(move |peer_str: String, method: Method, headers: HeaderMap, post_data: Bytes| {
s2.web_api_peer(peer_str, method, headers, post_data)
}))
)).try_bind_with_graceful_shutdown(
(IpAddr::from([127_u8, 0_u8, 0_u8, 1_u8]), local_config.settings.primary_port),
async { let _ = shutdown_rx.await; },
);
warp_server = warp::serve(warp::any()
.and(warp::path::end().map(|| { warp::reply::with_status("404", StatusCode::NOT_FOUND) })
.or(warp::path("status")
.and(warp::addr::remote())
.and(warp::method())
.and(warp::header::headers_cloned())
.and(warp::body::content_length_limit(1048576))
.and(warp::body::bytes())
.map(move |remote: Option<SocketAddr>, method: Method, headers: HeaderMap, post_data: Bytes| { s0.web_api_status(remote, method, headers, post_data) }))
.or(warp::path!("network" / String)
.and(warp::addr::remote())
.and(warp::method())
.and(warp::header::headers_cloned())
.and(warp::body::content_length_limit(1048576))
.and(warp::body::bytes())
.map(move |network_str: String, remote: Option<SocketAddr>, method: Method, headers: HeaderMap, post_data: Bytes| { s1.web_api_network(network_str, remote, method, headers, post_data) }))
.or(warp::path!("peer" / String)
.and(warp::addr::remote())
.and(warp::method())
.and(warp::header::headers_cloned())
.and(warp::body::content_length_limit(1048576))
.and(warp::body::bytes())
.map(move |peer_str: String, remote: Option<SocketAddr>, method: Method, headers: HeaderMap, post_data: Bytes| { s2.web_api_peer(peer_str, remote, method, headers, post_data) }))
)
).try_bind_with_graceful_shutdown((IpAddr::from([127_u8, 0_u8, 0_u8, 1_u8]), local_config.settings.primary_port), async { let _ = shutdown_rx.await; });
}
if warp_server.is_err() {
l!(log, "ERROR: local API http server failed to bind to port {} or failed to start: {}", local_config.settings.primary_port, warp_server.err().unwrap().to_string());
@ -244,6 +256,9 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
// Write zerotier.port which is used by the CLI to know how to reach the HTTP API.
store.write_port(local_config.settings.primary_port);
// The inner loop runs the web server in the "background" (async) while periodically
// scanning for significant configuration changes. Some major changes may require
// the inner loop to exit and be restarted.
let mut last_checked_config: i64 = 0;
loop {
let loop_start = ms_since_epoch();
@ -256,6 +271,7 @@ pub(crate) fn run(store: &Arc<Store>, auth_token: Option<String>) -> i32 {
now = ms_since_epoch();
let actual_delay = now - loop_start;
if actual_delay > ((loop_delay as i64) * 4_i64) {
l!(log, "likely sleep/wake detected, reestablishing links...");
// TODO: handle likely sleep/wake or other system interruption
}
},