diff options
Diffstat (limited to 'src/rust/protover')
-rw-r--r-- | src/rust/protover/Cargo.toml | 6 | ||||
-rw-r--r-- | src/rust/protover/errors.rs | 43 | ||||
-rw-r--r-- | src/rust/protover/ffi.rs | 65 | ||||
-rw-r--r-- | src/rust/protover/lib.rs | 9 | ||||
-rw-r--r-- | src/rust/protover/protoset.rs | 59 | ||||
-rw-r--r-- | src/rust/protover/protover.rs | 187 | ||||
-rw-r--r-- | src/rust/protover/tests/protover.rs | 26 |
7 files changed, 242 insertions, 153 deletions
diff --git a/src/rust/protover/Cargo.toml b/src/rust/protover/Cargo.toml index a8480e142a..2f7783e76c 100644 --- a/src/rust/protover/Cargo.toml +++ b/src/rust/protover/Cargo.toml @@ -4,6 +4,11 @@ version = "0.0.1" name = "protover" [features] +# We have to define a feature here because doctests don't get cfg(test), +# and we need to disable some C dependencies when running the doctests +# because of the various linker issues. See +# https://github.com/rust-lang/rust/issues/45599 +test_linking_hack = [] [dependencies] libc = "=0.2.39" @@ -27,4 +32,3 @@ path = "../tor_log" name = "protover" path = "lib.rs" crate_type = ["rlib", "staticlib"] - diff --git a/src/rust/protover/errors.rs b/src/rust/protover/errors.rs index d9dc73381f..f26a48b019 100644 --- a/src/rust/protover/errors.rs +++ b/src/rust/protover/errors.rs @@ -25,22 +25,33 @@ pub enum ProtoverError { impl Display for ProtoverError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - ProtoverError::Overlap - => write!(f, "Two or more (low, high) protover ranges would overlap once expanded."), - ProtoverError::LowGreaterThanHigh - => write!(f, "The low in a (low, high) protover range was greater than high."), - ProtoverError::Unparseable - => write!(f, "The protover string was unparseable."), - ProtoverError::ExceedsMax - => write!(f, "The high in a (low, high) protover range exceeds u32::MAX."), - ProtoverError::ExceedsExpansionLimit - => write!(f, "The protover string would exceed the maximum expansion limit."), - ProtoverError::UnknownProtocol - => write!(f, "A protocol in the protover string we attempted to parse is unknown."), - ProtoverError::ExceedsNameLimit - => write!(f, "An unrecognised protocol name was too long."), - ProtoverError::InvalidProtocol - => write!(f, "A protocol name includes invalid characters."), + ProtoverError::Overlap => write!( + f, + "Two or more (low, high) protover ranges would overlap once expanded." + ), + ProtoverError::LowGreaterThanHigh => write!( + f, + "The low in a (low, high) protover range was greater than high." + ), + ProtoverError::Unparseable => write!(f, "The protover string was unparseable."), + ProtoverError::ExceedsMax => write!( + f, + "The high in a (low, high) protover range exceeds u32::MAX." + ), + ProtoverError::ExceedsExpansionLimit => write!( + f, + "The protover string would exceed the maximum expansion limit." + ), + ProtoverError::UnknownProtocol => write!( + f, + "A protocol in the protover string we attempted to parse is unknown." + ), + ProtoverError::ExceedsNameLimit => { + write!(f, "An unrecognised protocol name was too long.") + } + ProtoverError::InvalidProtocol => { + write!(f, "A protocol name includes invalid characters.") + } } } } diff --git a/src/rust/protover/ffi.rs b/src/rust/protover/ffi.rs index e3e545db75..0c28d032c6 100644 --- a/src/rust/protover/ffi.rs +++ b/src/rust/protover/ffi.rs @@ -1,9 +1,9 @@ -// Copyright (c) 2016-2017, The Tor Project, Inc. */ +// Copyright (c) 2016-2018, The Tor Project, Inc. */ // See LICENSE for licensing information */ //! FFI functions, only to be called from C. //! -//! Equivalent C versions of this api are in `src/or/protover.c` +//! Equivalent C versions of this api are in `protover.c` use libc::{c_char, c_int, uint32_t}; use std::ffi::CStr; @@ -18,7 +18,7 @@ use protover::*; /// Translate C enums to Rust Proto enums, using the integer value of the C /// enum to map to its associated Rust enum. /// -/// C_RUST_COUPLED: src/or/protover.h `protocol_type_t` +/// C_RUST_COUPLED: protover.h `protocol_type_t` fn translate_to_rust(c_proto: uint32_t) -> Result<Protocol, ProtoverError> { match c_proto { 0 => Ok(Protocol::Link), @@ -42,7 +42,6 @@ pub extern "C" fn protover_all_supported( c_relay_version: *const c_char, missing_out: *mut *mut c_char, ) -> c_int { - if c_relay_version.is_null() { return 1; } @@ -58,13 +57,11 @@ pub extern "C" fn protover_all_supported( let relay_proto_entry: UnvalidatedProtoEntry = match UnvalidatedProtoEntry::from_str_any_len(relay_version) { - Ok(n) => n, - Err(_) => return 1, - }; - let maybe_unsupported: Option<UnvalidatedProtoEntry> = relay_proto_entry.all_supported(); + Ok(n) => n, + Err(_) => return 1, + }; - if maybe_unsupported.is_some() { - let unsupported: UnvalidatedProtoEntry = maybe_unsupported.unwrap(); + if let Some(unsupported) = relay_proto_entry.all_supported() { let c_unsupported: CString = match CString::new(unsupported.to_string()) { Ok(n) => n, Err(_) => return 1, @@ -100,23 +97,22 @@ pub extern "C" fn protocol_list_supports_protocol( Err(_) => return 1, }; let proto_entry: UnvalidatedProtoEntry = match protocol_list.parse() { - Ok(n) => n, + Ok(n) => n, Err(_) => return 0, }; let protocol: UnknownProtocol = match translate_to_rust(c_protocol) { Ok(n) => n.into(), Err(_) => return 0, }; - match proto_entry.supports_protocol(&protocol, &version) { - false => return 0, - true => return 1, + if proto_entry.supports_protocol(&protocol, &version) { + 1 + } else { + 0 } } #[no_mangle] -pub extern "C" fn protover_contains_long_protocol_names_( - c_protocol_list: *const c_char -) -> c_int { +pub extern "C" fn protover_contains_long_protocol_names_(c_protocol_list: *const c_char) -> c_int { if c_protocol_list.is_null() { return 1; } @@ -127,13 +123,10 @@ pub extern "C" fn protover_contains_long_protocol_names_( let protocol_list = match c_str.to_str() { Ok(n) => n, - Err(_) => return 1 + Err(_) => return 1, }; - let protocol_entry : Result<UnvalidatedProtoEntry,_> = - protocol_list.parse(); - - match protocol_entry { + match protocol_list.parse::<UnvalidatedProtoEntry>() { Ok(_) => 0, Err(_) => 1, } @@ -166,7 +159,7 @@ pub extern "C" fn protocol_list_supports_protocol_or_later( }; let proto_entry: UnvalidatedProtoEntry = match protocol_list.parse() { - Ok(n) => n, + Ok(n) => n, Err(_) => return 1, }; @@ -196,10 +189,8 @@ pub extern "C" fn protover_compute_vote( threshold: c_int, allow_long_proto_names: bool, ) -> *mut c_char { - if list.is_null() { - let empty = String::new(); - return allocate_and_copy_string(&empty); + return allocate_and_copy_string(""); } // Dereference of raw pointer requires an unsafe block. The pointer is @@ -209,13 +200,16 @@ pub extern "C" fn protover_compute_vote( let mut proto_entries: Vec<UnvalidatedProtoEntry> = Vec::new(); for datum in data { - let entry: UnvalidatedProtoEntry = match allow_long_proto_names { - true => match UnvalidatedProtoEntry::from_str_any_len(datum.as_str()) { - Ok(n) => n, - Err(_) => continue}, - false => match datum.parse() { - Ok(n) => n, - Err(_) => continue}, + let entry: UnvalidatedProtoEntry = if allow_long_proto_names { + match UnvalidatedProtoEntry::from_str_any_len(datum.as_str()) { + Ok(n) => n, + Err(_) => continue, + } + } else { + match datum.parse() { + Ok(n) => n, + Err(_) => continue, + } }; proto_entries.push(entry); } @@ -227,10 +221,7 @@ pub extern "C" fn protover_compute_vote( /// Provide an interface for C to translate arguments and return types for /// protover::is_supported_here #[no_mangle] -pub extern "C" fn protover_is_supported_here( - c_protocol: uint32_t, - version: uint32_t, -) -> c_int { +pub extern "C" fn protover_is_supported_here(c_protocol: uint32_t, version: uint32_t) -> c_int { let protocol = match translate_to_rust(c_protocol) { Ok(n) => n, Err(_) => return 0, diff --git a/src/rust/protover/lib.rs b/src/rust/protover/lib.rs index ce964196fd..9625cb58ad 100644 --- a/src/rust/protover/lib.rs +++ b/src/rust/protover/lib.rs @@ -1,4 +1,4 @@ -//! Copyright (c) 2016-2017, The Tor Project, Inc. */ +//! Copyright (c) 2016-2018, The Tor Project, Inc. */ //! See LICENSE for licensing information */ //! Versioning information for different pieces of the Tor protocol. @@ -22,18 +22,19 @@ //! protocols to develop independently, without having to claim compatibility //! with specific versions of Tor. -#[deny(missing_docs)] +// XXX: add missing docs +//#![deny(missing_docs)] +extern crate external; extern crate libc; extern crate smartlist; -extern crate external; extern crate tor_allocate; #[macro_use] extern crate tor_util; pub mod errors; +pub mod ffi; pub mod protoset; mod protover; -pub mod ffi; pub use protover::*; diff --git a/src/rust/protover/protoset.rs b/src/rust/protover/protoset.rs index 465b8f2850..c447186098 100644 --- a/src/rust/protover/protoset.rs +++ b/src/rust/protover/protoset.rs @@ -55,7 +55,7 @@ impl Default for ProtoSet { fn default() -> Self { let pairs: Vec<(Version, Version)> = Vec::new(); - ProtoSet{ pairs } + ProtoSet { pairs } } } @@ -75,7 +75,7 @@ impl<'a> ProtoSet { pairs.sort_unstable(); pairs.dedup(); - ProtoSet{ pairs }.is_ok() + ProtoSet { pairs }.is_ok() } } @@ -322,7 +322,7 @@ impl FromStr for ProtoSet { /// * there are greater than 2^16 version numbers to expand. /// /// # Examples - /// + /// /// ``` /// use std::str::FromStr; /// @@ -371,10 +371,10 @@ impl FromStr for ProtoSet { } else if p.contains('-') { let mut pair = p.splitn(2, '-'); - let low = pair.next().ok_or(ProtoverError::Unparseable)?; + let low = pair.next().ok_or(ProtoverError::Unparseable)?; let high = pair.next().ok_or(ProtoverError::Unparseable)?; - let lo: Version = low.parse().or(Err(ProtoverError::Unparseable))?; + let lo: Version = low.parse().or(Err(ProtoverError::Unparseable))?; let hi: Version = high.parse().or(Err(ProtoverError::Unparseable))?; if lo == u32::MAX || hi == u32::MAX { @@ -478,11 +478,11 @@ impl From<Vec<Version>> for ProtoSet { if has_range { let first: Version = match v.first() { Some(x) => *x, - None => continue, + None => continue, }; - let last: Version = match v.get(index) { + let last: Version = match v.get(index) { Some(x) => *x, - None => continue, + None => continue, }; debug_assert!(last == end, format!("last = {}, end = {}", last, end)); @@ -495,7 +495,7 @@ impl From<Vec<Version>> for ProtoSet { } else { let last: Version = match v.get(index) { Some(x) => *x, - None => continue, + None => continue, }; version_pairs.push((last, last)); v.remove(index); @@ -519,22 +519,22 @@ mod test { } macro_rules! assert_contains_each { - ($protoset:expr, $versions:expr) => ( + ($protoset:expr, $versions:expr) => { for version in $versions { assert!($protoset.contains(version)); } - ) + }; } macro_rules! test_protoset_contains_versions { - ($list:expr, $str:expr) => ( + ($list:expr, $str:expr) => { let versions: &[Version] = $list; let protoset: Result<ProtoSet, ProtoverError> = ProtoSet::from_str($str); assert!(protoset.is_ok()); let p = protoset.unwrap(); assert_contains_each!(p, versions); - ) + }; } #[test] @@ -594,26 +594,41 @@ mod test { #[test] fn test_versions_from_slice_overlap() { - assert_eq!(Err(ProtoverError::Overlap), ProtoSet::from_slice(&[(1, 3), (2, 4)])); + assert_eq!( + Err(ProtoverError::Overlap), + ProtoSet::from_slice(&[(1, 3), (2, 4)]) + ); } #[test] fn test_versions_from_str_max() { - assert_eq!(Err(ProtoverError::ExceedsMax), ProtoSet::from_str("4294967295")); + assert_eq!( + Err(ProtoverError::ExceedsMax), + ProtoSet::from_str("4294967295") + ); } #[test] fn test_versions_from_slice_max() { - assert_eq!(Err(ProtoverError::ExceedsMax), ProtoSet::from_slice(&[(4294967295, 4294967295)])); + assert_eq!( + Err(ProtoverError::ExceedsMax), + ProtoSet::from_slice(&[(4294967295, 4294967295)]) + ); } #[test] fn test_protoset_contains() { let protoset: ProtoSet = ProtoSet::from_slice(&[(1, 5), (7, 9), (13, 14)]).unwrap(); - for x in 1..6 { assert!(protoset.contains(&x), format!("should contain {}", x)); } - for x in 7..10 { assert!(protoset.contains(&x), format!("should contain {}", x)); } - for x in 13..15 { assert!(protoset.contains(&x), format!("should contain {}", x)); } + for x in 1..6 { + assert!(protoset.contains(&x), format!("should contain {}", x)); + } + for x in 7..10 { + assert!(protoset.contains(&x), format!("should contain {}", x)); + } + for x in 13..15 { + assert!(protoset.contains(&x), format!("should contain {}", x)); + } for x in [6, 10, 11, 12, 15, 42, 43, 44, 45, 1234584].iter() { assert!(!protoset.contains(&x), format!("should not contain {}", x)); @@ -624,7 +639,9 @@ mod test { fn test_protoset_contains_1_3() { let protoset: ProtoSet = ProtoSet::from_slice(&[(1, 3)]).unwrap(); - for x in 1..4 { assert!(protoset.contains(&x), format!("should contain {}", x)); } + for x in 1..4 { + assert!(protoset.contains(&x), format!("should contain {}", x)); + } } macro_rules! assert_protoset_from_vec_contains_all { @@ -650,7 +667,7 @@ mod test { #[test] fn test_protoset_from_vec_unordered() { - let v: Vec<Version> = vec!(2, 3, 8, 4, 3, 9, 7, 2); + let v: Vec<Version> = vec![2, 3, 8, 4, 3, 9, 7, 2]; let ps: ProtoSet = v.into(); assert_eq!(ps.to_string(), "2-4,7-9"); diff --git a/src/rust/protover/protover.rs b/src/rust/protover/protover.rs index 68027056c4..43822a3f15 100644 --- a/src/rust/protover/protover.rs +++ b/src/rust/protover/protover.rs @@ -1,8 +1,8 @@ -// Copyright (c) 2016-2017, The Tor Project, Inc. */ +// Copyright (c) 2016-2018, The Tor Project, Inc. */ // See LICENSE for licensing information */ -use std::collections::HashMap; use std::collections::hash_map; +use std::collections::HashMap; use std::ffi::CStr; use std::fmt; use std::str; @@ -12,28 +12,28 @@ use std::string::String; use external::c_tor_version_as_new_as; use errors::ProtoverError; -use protoset::Version; use protoset::ProtoSet; +use protoset::Version; /// The first version of Tor that included "proto" entries in its descriptors. /// Authorities should use this to decide whether to guess proto lines. /// /// C_RUST_COUPLED: -/// src/or/protover.h `FIRST_TOR_VERSION_TO_ADVERTISE_PROTOCOLS` +/// protover.h `FIRST_TOR_VERSION_TO_ADVERTISE_PROTOCOLS` const FIRST_TOR_VERSION_TO_ADVERTISE_PROTOCOLS: &'static str = "0.2.9.3-alpha"; /// The maximum number of subprotocol version numbers we will attempt to expand /// before concluding that someone is trying to DoS us /// -/// C_RUST_COUPLED: src/or/protover.c `MAX_PROTOCOLS_TO_EXPAND` -const MAX_PROTOCOLS_TO_EXPAND: usize = (1<<16); +/// C_RUST_COUPLED: protover.c `MAX_PROTOCOLS_TO_EXPAND` +const MAX_PROTOCOLS_TO_EXPAND: usize = (1 << 16); /// The maximum size an `UnknownProtocol`'s name may be. pub(crate) const MAX_PROTOCOL_NAME_LENGTH: usize = 100; /// Known subprotocols in Tor. Indicates which subprotocol a relay supports. /// -/// C_RUST_COUPLED: src/or/protover.h `protocol_type_t` +/// C_RUST_COUPLED: protover.h `protocol_type_t` #[derive(Clone, Hash, Eq, PartialEq, Debug)] pub enum Protocol { Cons, @@ -57,7 +57,7 @@ impl fmt::Display for Protocol { /// Translates a string representation of a protocol into a Proto type. /// Error if the string is an unrecognized protocol name. /// -/// C_RUST_COUPLED: src/or/protover.c `PROTOCOL_NAMES` +/// C_RUST_COUPLED: protover.c `PROTOCOL_NAMES` impl FromStr for Protocol { type Err = ProtoverError; @@ -124,6 +124,17 @@ impl From<Protocol> for UnknownProtocol { } } +#[cfg(feature="test_linking_hack")] +fn have_linkauth_v1() -> bool { + true +} + +#[cfg(not(feature="test_linking_hack"))] +fn have_linkauth_v1() -> bool { + use external::c_tor_is_using_nss; + ! c_tor_is_using_nss() +} + /// Get a CStr representation of current supported protocols, for /// passing to C, or for converting to a `&str` for Rust. /// @@ -139,18 +150,33 @@ impl From<Protocol> for UnknownProtocol { /// Rust code can use the `&'static CStr` as a normal `&'a str` by /// calling `protover::get_supported_protocols`. /// -// C_RUST_COUPLED: src/or/protover.c `protover_get_supported_protocols` +// C_RUST_COUPLED: protover.c `protover_get_supported_protocols` pub(crate) fn get_supported_protocols_cstr() -> &'static CStr { - cstr!("Cons=1-2 \ - Desc=1-2 \ - DirCache=1-2 \ - HSDir=1-2 \ - HSIntro=3-4 \ - HSRend=1-2 \ - Link=1-5 \ - LinkAuth=1,3 \ - Microdesc=1-2 \ - Relay=1-2") + if ! have_linkauth_v1() { + cstr!("Cons=1-2 \ + Desc=1-2 \ + DirCache=1-2 \ + HSDir=1-2 \ + HSIntro=3-4 \ + HSRend=1-2 \ + Link=1-5 \ + LinkAuth=3 \ + Microdesc=1-2 \ + Relay=1-2" + ) + } else { + cstr!("Cons=1-2 \ + Desc=1-2 \ + DirCache=1-2 \ + HSDir=1-2 \ + HSIntro=3-4 \ + HSRend=1-2 \ + Link=1-5 \ + LinkAuth=1,3 \ + Microdesc=1-2 \ + Relay=1-2" + ) + } } /// A map of protocol names to the versions of them which are supported. @@ -159,7 +185,7 @@ pub struct ProtoEntry(HashMap<Protocol, ProtoSet>); impl Default for ProtoEntry { fn default() -> ProtoEntry { - ProtoEntry( HashMap::new() ) + ProtoEntry(HashMap::new()) } } @@ -213,9 +239,7 @@ impl FromStr for ProtoEntry { /// /// # Returns /// - /// A `Result` whose `Ok` value is a `ProtoEntry`, where the - /// first element is the subprotocol type (see `protover::Protocol`) and the last - /// element is an ordered set of `(low, high)` unique version numbers which are supported. + /// A `Result` whose `Ok` value is a `ProtoEntry`. /// Otherwise, the `Err` value of this `Result` is a `ProtoverError`. fn from_str(protocol_entry: &str) -> Result<ProtoEntry, ProtoverError> { let mut proto_entry: ProtoEntry = ProtoEntry::default(); @@ -249,7 +273,7 @@ impl FromStr for ProtoEntry { /// Generate an implementation of `ToString` for either a `ProtoEntry` or an /// `UnvalidatedProtoEntry`. macro_rules! impl_to_string_for_proto_entry { - ($t:ty) => ( + ($t:ty) => { impl ToString for $t { fn to_string(&self) -> String { let mut parts: Vec<String> = Vec::new(); @@ -261,7 +285,7 @@ macro_rules! impl_to_string_for_proto_entry { parts.join(" ") } } - ) + }; } impl_to_string_for_proto_entry!(ProtoEntry); @@ -275,7 +299,7 @@ pub struct UnvalidatedProtoEntry(HashMap<UnknownProtocol, ProtoSet>); impl Default for UnvalidatedProtoEntry { fn default() -> UnvalidatedProtoEntry { - UnvalidatedProtoEntry( HashMap::new() ) + UnvalidatedProtoEntry(HashMap::new()) } } @@ -333,7 +357,7 @@ impl UnvalidatedProtoEntry { pub fn all_supported(&self) -> Option<UnvalidatedProtoEntry> { let mut unsupported: UnvalidatedProtoEntry = UnvalidatedProtoEntry::default(); let supported: ProtoEntry = match ProtoEntry::supported() { - Ok(x) => x, + Ok(x) => x, Err(_) => return None, }; @@ -459,11 +483,12 @@ impl UnvalidatedProtoEntry { /// following are true: /// /// * If a protocol name is an empty string, e.g. `"Cons=1,3 =3-5"`. - /// * If a protocol name cannot be parsed as utf-8. - /// * If the version numbers are an empty string, e.g. `"Cons="`. - fn parse_protocol_and_version_str<'a>(protocol_string: &'a str) - -> Result<Vec<(&'a str, &'a str)>, ProtoverError> - { + /// * If an entry has no equals sign, e.g. `"Cons=1,3 Desc"`. + /// * If there is leading or trailing whitespace, e.g. `" Cons=1,3 Link=3"`. + /// * If there is any other extra whitespice, e.g. `"Cons=1,3 Link=3"`. + fn parse_protocol_and_version_str<'a>( + protocol_string: &'a str, + ) -> Result<Vec<(&'a str, &'a str)>, ProtoverError> { let mut protovers: Vec<(&str, &str)> = Vec::new(); for subproto in protocol_string.split(' ') { @@ -499,11 +524,9 @@ impl FromStr for UnvalidatedProtoEntry { /// /// # Returns /// - /// A `Result` whose `Ok` value is a `ProtoSet` holding all of the - /// unique version numbers. + /// A `Result` whose `Ok` value is an `UnvalidatedProtoEntry`. /// - /// The returned `Result`'s `Err` value is an `ProtoverError` whose `Display` - /// impl has a description of the error. + /// The returned `Result`'s `Err` value is an `ProtoverError`. /// /// # Errors /// @@ -530,9 +553,9 @@ impl FromStr for UnvalidatedProtoEntry { impl UnvalidatedProtoEntry { /// Create an `UnknownProtocol`, ignoring whether or not it /// exceeds MAX_PROTOCOL_NAME_LENGTH. - pub(crate) fn from_str_any_len(protocol_string: &str) - -> Result<UnvalidatedProtoEntry, ProtoverError> - { + pub(crate) fn from_str_any_len( + protocol_string: &str, + ) -> Result<UnvalidatedProtoEntry, ProtoverError> { let mut parsed: UnvalidatedProtoEntry = UnvalidatedProtoEntry::default(); let parts: Vec<(&str, &str)> = UnvalidatedProtoEntry::parse_protocol_and_version_str(protocol_string)?; @@ -567,11 +590,11 @@ impl From<ProtoEntry> for UnvalidatedProtoEntry { /// The "protocols" are *not* guaranteed to be known/supported `Protocol`s, in /// order to allow new subprotocols to be introduced even if Directory /// Authorities don't yet know of them. -pub struct ProtoverVote( HashMap<UnknownProtocol, HashMap<Version, usize>> ); +pub struct ProtoverVote(HashMap<UnknownProtocol, HashMap<Version, usize>>); impl Default for ProtoverVote { fn default() -> ProtoverVote { - ProtoverVote( HashMap::new() ) + ProtoverVote(HashMap::new()) } } @@ -585,9 +608,10 @@ impl IntoIterator for ProtoverVote { } impl ProtoverVote { - pub fn entry(&mut self, key: UnknownProtocol) - -> hash_map::Entry<UnknownProtocol, HashMap<Version, usize>> - { + pub fn entry( + &mut self, + key: UnknownProtocol, + ) -> hash_map::Entry<UnknownProtocol, HashMap<Version, usize>> { self.0.entry(key) } @@ -608,8 +632,11 @@ impl ProtoverVote { /// let vote = ProtoverVote::compute(protos, &2); /// assert_eq!("Link=3", vote.to_string()); /// ``` - // C_RUST_COUPLED: /src/or/protover.c protover_compute_vote - pub fn compute(proto_entries: &[UnvalidatedProtoEntry], threshold: &usize) -> UnvalidatedProtoEntry { + // C_RUST_COUPLED: protover.c protover_compute_vote + pub fn compute( + proto_entries: &[UnvalidatedProtoEntry], + threshold: &usize, + ) -> UnvalidatedProtoEntry { let mut all_count: ProtoverVote = ProtoverVote::default(); let mut final_output: UnvalidatedProtoEntry = UnvalidatedProtoEntry::default(); @@ -635,8 +662,7 @@ impl ProtoverVote { all_count.entry(protocol.clone()).or_insert(HashMap::new()); for version in versions.clone().expand() { - let counter: &mut usize = - supported_vers.entry(version).or_insert(0); + let counter: &mut usize = supported_vers.entry(version).or_insert(0); *counter += 1; } } @@ -715,16 +741,22 @@ pub(crate) fn compute_for_old_tor_cstr(version: &str) -> &'static CStr { return empty; } if c_tor_version_as_new_as(version, "0.2.9.1-alpha") { - return cstr!("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 \ - Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2"); + return cstr!( + "Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1-2 \ + Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2" + ); } if c_tor_version_as_new_as(version, "0.2.7.5") { - return cstr!("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 \ - Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2"); + return cstr!( + "Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 \ + Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2" + ); } if c_tor_version_as_new_as(version, "0.2.4.19") { - return cstr!("Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 \ - Link=1-4 LinkAuth=1 Microdesc=1 Relay=1-2"); + return cstr!( + "Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 \ + Link=1-4 LinkAuth=1 Microdesc=1 Relay=1-2" + ); } empty } @@ -759,7 +791,9 @@ pub(crate) fn compute_for_old_tor_cstr(version: &str) -> &'static CStr { pub fn compute_for_old_tor(version: &str) -> Result<&'static str, ProtoverError> { // .to_str() fails with a Utf8Error if it couldn't validate the // utf-8, so convert that here into an Unparseable ProtoverError. - compute_for_old_tor_cstr(version).to_str().or(Err(ProtoverError::Unparseable)) + compute_for_old_tor_cstr(version) + .to_str() + .or(Err(ProtoverError::Unparseable)) } #[cfg(test)] @@ -793,19 +827,19 @@ mod test { } macro_rules! assert_protoentry_is_parseable { - ($e:expr) => ( + ($e:expr) => { let protoentry: Result<ProtoEntry, ProtoverError> = $e.parse(); assert!(protoentry.is_ok(), format!("{:?}", protoentry.err())); - ) + }; } macro_rules! assert_protoentry_is_unparseable { - ($e:expr) => ( + ($e:expr) => { let protoentry: Result<ProtoEntry, ProtoverError> = $e.parse(); assert!(protoentry.is_err()); - ) + }; } #[test] @@ -891,24 +925,45 @@ mod test { #[test] fn test_contract_protocol_list() { let mut versions = ""; - assert_eq!(String::from(versions), ProtoSet::from_str(&versions).unwrap().to_string()); + assert_eq!( + String::from(versions), + ProtoSet::from_str(&versions).unwrap().to_string() + ); versions = "1"; - assert_eq!(String::from(versions), ProtoSet::from_str(&versions).unwrap().to_string()); + assert_eq!( + String::from(versions), + ProtoSet::from_str(&versions).unwrap().to_string() + ); versions = "1-2"; - assert_eq!(String::from(versions), ProtoSet::from_str(&versions).unwrap().to_string()); + assert_eq!( + String::from(versions), + ProtoSet::from_str(&versions).unwrap().to_string() + ); versions = "1,3"; - assert_eq!(String::from(versions), ProtoSet::from_str(&versions).unwrap().to_string()); + assert_eq!( + String::from(versions), + ProtoSet::from_str(&versions).unwrap().to_string() + ); versions = "1-4"; - assert_eq!(String::from(versions), ProtoSet::from_str(&versions).unwrap().to_string()); + assert_eq!( + String::from(versions), + ProtoSet::from_str(&versions).unwrap().to_string() + ); versions = "1,3,5-7"; - assert_eq!(String::from(versions), ProtoSet::from_str(&versions).unwrap().to_string()); + assert_eq!( + String::from(versions), + ProtoSet::from_str(&versions).unwrap().to_string() + ); versions = "1-3,500"; - assert_eq!(String::from(versions), ProtoSet::from_str(&versions).unwrap().to_string()); + assert_eq!( + String::from(versions), + ProtoSet::from_str(&versions).unwrap().to_string() + ); } } diff --git a/src/rust/protover/tests/protover.rs b/src/rust/protover/tests/protover.rs index 9258d869d7..86e276cf73 100644 --- a/src/rust/protover/tests/protover.rs +++ b/src/rust/protover/tests/protover.rs @@ -1,12 +1,12 @@ -// Copyright (c) 2016-2017, The Tor Project, Inc. */ +// Copyright (c) 2016-2018, The Tor Project, Inc. */ // See LICENSE for licensing information */ extern crate protover; +use protover::errors::ProtoverError; use protover::ProtoEntry; use protover::ProtoverVote; use protover::UnvalidatedProtoEntry; -use protover::errors::ProtoverError; #[test] fn parse_protocol_with_single_proto_and_single_version() { @@ -179,14 +179,16 @@ fn protover_compute_vote_returns_two_protocols_for_two_matching() { #[test] fn protover_compute_vote_returns_one_protocol_when_one_out_of_two_matches() { - let protocols: &[UnvalidatedProtoEntry] = &["Cons=1 Link=2".parse().unwrap(), "Cons=1".parse().unwrap()]; + let protocols: &[UnvalidatedProtoEntry] = + &["Cons=1 Link=2".parse().unwrap(), "Cons=1".parse().unwrap()]; let listed = ProtoverVote::compute(protocols, &2); assert_eq!("Cons=1", listed.to_string()); } #[test] fn protover_compute_vote_returns_protocols_that_it_doesnt_currently_support() { - let protocols: &[UnvalidatedProtoEntry] = &["Foo=1 Cons=2".parse().unwrap(), "Bar=1".parse().unwrap()]; + let protocols: &[UnvalidatedProtoEntry] = + &["Foo=1 Cons=2".parse().unwrap(), "Bar=1".parse().unwrap()]; let listed = ProtoverVote::compute(protocols, &1); assert_eq!("Bar=1 Cons=2 Foo=1", listed.to_string()); } @@ -222,10 +224,12 @@ fn protover_compute_vote_returns_matching_for_longer_mix_with_threshold_two() { #[test] fn protover_compute_vote_handles_duplicated_versions() { - let protocols: &[UnvalidatedProtoEntry] = &["Cons=1".parse().unwrap(), "Cons=1".parse().unwrap()]; + let protocols: &[UnvalidatedProtoEntry] = + &["Cons=1".parse().unwrap(), "Cons=1".parse().unwrap()]; assert_eq!("Cons=1", ProtoverVote::compute(protocols, &2).to_string()); - let protocols: &[UnvalidatedProtoEntry] = &["Cons=1-2".parse().unwrap(), "Cons=1-2".parse().unwrap()]; + let protocols: &[UnvalidatedProtoEntry] = + &["Cons=1-2".parse().unwrap(), "Cons=1-2".parse().unwrap()]; assert_eq!("Cons=1-2", ProtoverVote::compute(protocols, &2).to_string()); } @@ -246,12 +250,18 @@ fn parse_protocol_with_single_protocol_and_two_nonsequential_versions() { #[test] fn protover_is_supported_here_returns_true_for_supported_protocol() { - assert_eq!(true, protover::is_supported_here(&protover::Protocol::Cons, &1)); + assert_eq!( + true, + protover::is_supported_here(&protover::Protocol::Cons, &1) + ); } #[test] fn protover_is_supported_here_returns_false_for_unsupported_protocol() { - assert_eq!(false, protover::is_supported_here(&protover::Protocol::Cons, &5)); + assert_eq!( + false, + protover::is_supported_here(&protover::Protocol::Cons, &5) + ); } #[test] |