Build fixes, add some standard derives.

This commit is contained in:
Adam Ierymenko 2021-03-17 17:53:24 -04:00
parent f38f40693f
commit c0bab849ef
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
6 changed files with 63 additions and 63 deletions

View file

@ -59,12 +59,14 @@ impl Buffer {
self.zt_core_buf self.zt_core_buf
} }
/// Set the size of the data held by this buffer. This is unsafe because /// Set the size of the data held by this buffer.
/// setting it to a value larger than CAPACITY will place the buffer into /// This is usually called after writing data into the buffer.
/// an invalid state.
#[inline(always)] #[inline(always)]
pub unsafe fn set_len(&mut self, s: usize) { pub fn set_len(&mut self, s: usize) {
self.data_size = s; // CAPACITY will always be a power of two, so we can just mask this
// to make this safe. This is a sanity check to make it impossible to
// set this to an invalid size.
self.data_size = s & (Buffer::CAPACITY - 1);
} }
} }

View file

@ -41,7 +41,7 @@ pub const CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE: u32 = ztcore::ZT_C
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(PartialEq, Eq, PartialOrd, Ord)] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct CertificateSerialNo(pub [u8; 48]); pub struct CertificateSerialNo(pub [u8; 48]);
impl CertificateSerialNo { impl CertificateSerialNo {
@ -87,7 +87,7 @@ impl<'de> serde::Deserialize<'de> for CertificateSerialNo {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Type of certificate subject unique ID /// Type of certificate subject unique ID
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq, Clone, Copy)]
pub enum CertificateUniqueIdType { pub enum CertificateUniqueIdType {
NistP384 = ztcore::ZT_CertificateUniqueIdType_ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384 as isize NistP384 = ztcore::ZT_CertificateUniqueIdType_ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384 as isize
} }
@ -124,7 +124,7 @@ impl<'de> serde::Deserialize<'de> for CertificateUniqueIdType {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize, PartialEq, Eq)] #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct CertificateSubjectUniqueIdSecret { pub struct CertificateSubjectUniqueIdSecret {
#[serde(with = "Base64Standard")] #[serde(with = "Base64Standard")]
pub public: Vec<u8>, pub public: Vec<u8>,
@ -160,7 +160,7 @@ implement_to_from_json!(CertificateSubjectUniqueIdSecret);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)] #[derive(FromPrimitive, ToPrimitive, PartialEq, Eq, Clone, Copy)]
pub enum CertificateError { pub enum CertificateError {
None = ztcore::ZT_CertificateError_ZT_CERTIFICATE_ERROR_NONE as isize, None = ztcore::ZT_CertificateError_ZT_CERTIFICATE_ERROR_NONE as isize,
HaveNewerCert = ztcore::ZT_CertificateError_ZT_CERTIFICATE_ERROR_HAVE_NEWER_CERT as isize, HaveNewerCert = ztcore::ZT_CertificateError_ZT_CERTIFICATE_ERROR_HAVE_NEWER_CERT as isize,
@ -225,7 +225,7 @@ impl<'de> serde::Deserialize<'de> for CertificateError {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize, PartialEq, Eq)] #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct CertificateName { pub struct CertificateName {
#[serde(rename = "serialNo")] #[serde(rename = "serialNo")]
pub serial_no: String, pub serial_no: String,
@ -317,7 +317,7 @@ implement_to_from_json!(CertificateName);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize, PartialEq, Eq)] #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct CertificateNetwork { pub struct CertificateNetwork {
pub id: NetworkId, pub id: NetworkId,
pub controller: Option<Fingerprint>, pub controller: Option<Fingerprint>,
@ -366,7 +366,7 @@ implement_to_from_json!(CertificateNetwork);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize, PartialEq, Eq)] #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct CertificateIdentity { pub struct CertificateIdentity {
pub identity: Identity, pub identity: Identity,
pub locator: Option<Locator>, pub locator: Option<Locator>,
@ -395,7 +395,7 @@ implement_to_from_json!(CertificateIdentity);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize, PartialEq, Eq)] #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct CertificateSubject { pub struct CertificateSubject {
pub timestamp: i64, pub timestamp: i64,
pub identities: Vec<CertificateIdentity>, pub identities: Vec<CertificateIdentity>,
@ -578,7 +578,7 @@ implement_to_from_json!(CertificateSubject);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize, PartialEq, Eq)] #[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct Certificate { pub struct Certificate {
#[serde(rename = "serialNo")] #[serde(rename = "serialNo")]
pub serial_no: CertificateSerialNo, pub serial_no: CertificateSerialNo,

View file

@ -80,9 +80,6 @@ fn bind_udp_socket(_device_name: &str, address: &InetAddress) -> Result<FastUDPR
setsockopt_results |= osdep::setsockopt(s, osdep::SOL_SOCKET.as_(), osdep::SO_NOSIGPIPE.as_(), (&mut fl as *mut c_int).cast(), fl_size) setsockopt_results |= osdep::setsockopt(s, osdep::SOL_SOCKET.as_(), osdep::SO_NOSIGPIPE.as_(), (&mut fl as *mut c_int).cast(), fl_size)
} }
// On linux we bind to device so default route override can work. This
// is not required on BSDs as they behave this way if the socket is
// bound to the device's address.
#[cfg(target_os = "linux")] { #[cfg(target_os = "linux")] {
if !_device_name.is_empty() { if !_device_name.is_empty() {
unsafe { unsafe {
@ -131,7 +128,6 @@ fn bind_udp_socket(_device_name: &str, address: &InetAddress) -> Result<FastUDPR
} }
if osdep::bind(s, (address as *const InetAddress).cast(), sa_len) != 0 { if osdep::bind(s, (address as *const InetAddress).cast(), sa_len) != 0 {
//osdep::perror(std::ptr::null());
osdep::close(s); osdep::close(s);
return Err("bind to address failed"); return Err("bind to address failed");
} }

View file

@ -28,6 +28,7 @@ mod weblistener;
mod osdep; // bindgen generated mod osdep; // bindgen generated
use std::boxed::Box; use std::boxed::Box;
use std::io::Write;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use std::str::FromStr; use std::str::FromStr;
@ -133,23 +134,30 @@ Advanced Operations:
An <address> may be specified as a 10-digit short ZeroTier address, a An <address> may be specified as a 10-digit short ZeroTier address, a
fingerprint containing both an address and a SHA384 hash, or an identity. fingerprint containing both an address and a SHA384 hash, or an identity.
Identities and locators can be specified as either paths to files on the Identities and locators can be specified as either paths to files on the
filesystem or verbatim objects in string format. This is auto-detected."###, ver.0, ver.1, ver.2) filesystem or verbatim objects in string format. This is auto-detected.
"###, ver.0, ver.1, ver.2)
} }
pub(crate) fn print_help() { pub(crate) fn print_help() {
println!("{}", make_help()); let h = make_help();
std::io::stdout().write_all(h.as_bytes());
} }
fn is_bool(v: String) -> Result<(), String> { pub(crate) fn parse_bool(v: &str) -> Result<bool, String> {
if !v.is_empty() { if !v.is_empty() {
match v.chars().next().unwrap() { match v.chars().next().unwrap() {
'y' | 'Y' | '1' | 't' | 'T' | 'n' | 'N' | '0' | 'f' | 'F' => { return Ok(()); } 'y' | 'Y' | '1' | 't' | 'T' => { return Ok(true); }
'n' | 'N' | '0' | 'f' | 'F' => { return Ok(false); }
_ => {} _ => {}
} }
} }
Err(format!("invalid boolean value: '{}'", v)) Err(format!("invalid boolean value: '{}'", v))
} }
fn is_valid_bool(v: String) -> Result<(), String> {
parse_bool(v.as_str()).map(|_| ())
}
fn is_valid_port(v: String) -> Result<(), String> { fn is_valid_port(v: String) -> Result<(), String> {
let i = u16::from_str(v.as_str()).unwrap_or(0); let i = u16::from_str(v.as_str()).unwrap_or(0);
if i >= 1 { if i >= 1 {
@ -158,6 +166,17 @@ fn is_valid_port(v: String) -> Result<(), String> {
Err(format!("invalid TCP/IP port number: {}", v)) Err(format!("invalid TCP/IP port number: {}", v))
} }
fn make_store(cli_args: &ArgMatches) -> Arc<Store> {
//let json_output = cli_args.is_present("json"); // TODO
let zerotier_path = cli_args.value_of("path").map_or_else(|| unsafe { zerotier_core::cstr_to_string(osdep::platformDefaultHomePath(), -1) }, |ztp| ztp.to_string());
let store = Store::new(zerotier_path.as_str(), cli_args.value_of("token_path").map_or(None, |tp| Some(tp.to_string())), cli_args.value_of("token").map_or(None, |tok| Some(tok.trim().to_string())));
if store.is_err() {
eprintln!("FATAL: error accessing directory '{}': {}", zerotier_path, store.err().unwrap().to_string());
std::process::exit(1);
}
Arc::new(store.unwrap())
}
fn main() { fn main() {
let cli_args = { let cli_args = {
let help = make_help(); let help = make_help();
@ -177,12 +196,12 @@ fn main() {
.subcommand(App::new("blacklist") .subcommand(App::new("blacklist")
.subcommand(App::new("cidr") .subcommand(App::new("cidr")
.arg(Arg::with_name("ip_bits").index(1)) .arg(Arg::with_name("ip_bits").index(1))
.arg(Arg::with_name("boolean").index(2).validator(is_bool))) .arg(Arg::with_name("boolean").index(2).validator(is_valid_bool)))
.subcommand(App::new("if") .subcommand(App::new("if")
.arg(Arg::with_name("prefix").index(1)) .arg(Arg::with_name("prefix").index(1))
.arg(Arg::with_name("boolean").index(2).validator(is_bool)))) .arg(Arg::with_name("boolean").index(2).validator(is_valid_bool))))
.subcommand(App::new("portmap") .subcommand(App::new("portmap")
.arg(Arg::with_name("boolean").index(1).validator(is_bool)))) .arg(Arg::with_name("boolean").index(1).validator(is_valid_bool))))
.subcommand(App::new("peer") .subcommand(App::new("peer")
.subcommand(App::new("show") .subcommand(App::new("show")
.arg(Arg::with_name("address").index(1).required(true))) .arg(Arg::with_name("address").index(1).required(true)))
@ -286,17 +305,6 @@ fn main() {
args args
}; };
let store = || {
//let json_output = cli_args.is_present("json"); // TODO
let zerotier_path = cli_args.value_of("path").map_or_else(|| unsafe { zerotier_core::cstr_to_string(osdep::platformDefaultHomePath(), -1) }, |ztp| ztp.to_string());
let store = Store::new(zerotier_path.as_str(), cli_args.value_of("token_path").map_or(None, |tp| Some(tp.to_string())), cli_args.value_of("token").map_or(None, |tok| Some(tok.trim().to_string())));
if store.is_err() {
eprintln!("FATAL: error accessing directory '{}': {}", zerotier_path, store.err().unwrap().to_string());
std::process::exit(1);
}
Arc::new(store.unwrap())
};
std::process::exit(match cli_args.subcommand() { std::process::exit(match cli_args.subcommand() {
("help", None) => { ("help", None) => {
print_help(); print_help();
@ -314,14 +322,14 @@ fn main() {
("join", Some(sub_cli_args)) => { 0 } ("join", Some(sub_cli_args)) => { 0 }
("leave", Some(sub_cli_args)) => { 0 } ("leave", Some(sub_cli_args)) => { 0 }
("service", None) => { ("service", None) => {
let store = store(); let store = make_store(&cli_args);
drop(cli_args); // try to let go of unnecessary heap before running service drop(cli_args); // free memory
service::run(store) service::run(store)
}, },
("controller", Some(sub_cli_args)) => { 0 } ("controller", Some(sub_cli_args)) => { 0 }
("identity", Some(sub_cli_args)) => crate::commands::identity::run(sub_cli_args), ("identity", Some(sub_cli_args)) => crate::commands::identity::run(sub_cli_args),
("locator", Some(sub_cli_args)) => crate::commands::locator::run(sub_cli_args), ("locator", Some(sub_cli_args)) => crate::commands::locator::run(sub_cli_args),
("cert", Some(sub_cli_args)) => crate::commands::cert::run(store(), sub_cli_args), ("cert", Some(sub_cli_args)) => crate::commands::cert::run(make_store(&cli_args), sub_cli_args),
_ => { _ => {
print_help(); print_help();
1 1

View file

@ -95,7 +95,7 @@ impl NodeEventHandler<Network> for Service {
TraceEventLayer::VL2 => local_config.settings.log.vl2, TraceEventLayer::VL2 => local_config.settings.log.vl2,
TraceEventLayer::VL2Filter => local_config.settings.log.vl2_trace_rules, TraceEventLayer::VL2Filter => local_config.settings.log.vl2_trace_rules,
TraceEventLayer::VL2Multicast => local_config.settings.log.vl2_trace_multicast, TraceEventLayer::VL2Multicast => local_config.settings.log.vl2_trace_multicast,
TraceEventLayer::Other => true, _ => true,
} { } {
self.log.log(tm.to_string()); self.log.log(tm.to_string());
} }

View file

@ -28,7 +28,6 @@ use crate::service::Service;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
/// Handles API dispatch and other HTTP handler stuff. /// Handles API dispatch and other HTTP handler stuff.
#[inline(always)]
async fn web_handler(service: Service, req: Request<Body>) -> Result<Response<Body>, Infallible> { async fn web_handler(service: Service, req: Request<Body>) -> Result<Response<Body>, Infallible> {
Ok(Response::new("Hello, World".into())) Ok(Response::new("Hello, World".into()))
} }
@ -45,23 +44,26 @@ impl WebListener {
/// Create a new "background" TCP WebListener using the current tokio reactor async runtime. /// Create a new "background" TCP WebListener using the current tokio reactor async runtime.
pub fn new(_device_name: &str, addr: SocketAddr, service: &Service) -> Result<WebListener, Box<dyn std::error::Error>> { pub fn new(_device_name: &str, addr: SocketAddr, service: &Service) -> Result<WebListener, Box<dyn std::error::Error>> {
let listener = if addr.is_ipv4() { let listener = if addr.is_ipv4() {
let l = socket2::Socket::new(socket2::Domain::ipv4(), socket2::Type::stream(), Some(socket2::Protocol::tcp())); let listener = socket2::Socket::new(socket2::Domain::ipv4(), socket2::Type::stream(), Some(socket2::Protocol::tcp()));
if l.is_err() { if listener.is_err() {
return Err(Box::new(l.err().unwrap())); return Err(Box::new(listener.err().unwrap()));
} }
let l = l.unwrap(); let listener = listener.unwrap();
#[cfg(unix)] { #[cfg(unix)] {
let _ = l.set_reuse_port(true); let _ = listener.set_reuse_port(true);
} }
l listener
} else { } else {
let l = socket2::Socket::new(socket2::Domain::ipv6(), socket2::Type::stream(), Some(socket2::Protocol::tcp())); let listener = socket2::Socket::new(socket2::Domain::ipv6(), socket2::Type::stream(), Some(socket2::Protocol::tcp()));
if l.is_err() { if listener.is_err() {
return Err(Box::new(l.err().unwrap())); return Err(Box::new(listener.err().unwrap()));
} }
let l = l.unwrap(); let listener = listener.unwrap();
let _ = l.set_only_v6(true); #[cfg(unix)] {
l let _ = listener.set_reuse_port(true);
}
let _ = listener.set_only_v6(true);
listener
}; };
#[cfg(target_os = "linux")] { #[cfg(target_os = "linux")] {
@ -70,12 +72,7 @@ impl WebListener {
unsafe { unsafe {
let _ = std::ffi::CString::new(_device_name).map(|dn| { let _ = std::ffi::CString::new(_device_name).map(|dn| {
let dnb = dn.as_bytes_with_nul(); let dnb = dn.as_bytes_with_nul();
let _ = crate::osdep::setsockopt( let _ = crate::osdep::setsockopt(sock as std::os::raw::c_int, crate::osdep::SOL_SOCKET as std::os::raw::c_int, crate::osdep::SO_BINDTODEVICE as std::os::raw::c_int, dnb.as_ptr().cast(), (dnb.len() - 1) as crate::osdep::socklen_t);
sock as std::os::raw::c_int,
crate::osdep::SOL_SOCKET as std::os::raw::c_int,
crate::osdep::SO_BINDTODEVICE as std::os::raw::c_int,
dnb.as_ptr().cast(),
(dnb.len() - 1) as crate::osdep::socklen_t);
}); });
} }
} }
@ -94,10 +91,7 @@ impl WebListener {
if builder.is_err() { if builder.is_err() {
return Err(Box::new(builder.err().unwrap())); return Err(Box::new(builder.err().unwrap()));
} }
let builder = builder.unwrap() let builder = builder.unwrap().http1_half_close(false).http1_keepalive(true).http1_max_buf_size(131072);
.http1_half_close(false)
.http1_keepalive(true)
.http1_max_buf_size(131072);
let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>(); let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>();
let service = service.clone(); let service = service.clone();