[tor-commits] [tor/master] Rust implementation of protocol_list_supports_protocol_or_later()

nickm at torproject.org nickm at torproject.org
Thu Nov 9 14:42:48 UTC 2017


commit c80bb04542b4a56f2c174b526006f6d3e402eecc
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Nov 9 09:42:09 2017 -0500

    Rust implementation of protocol_list_supports_protocol_or_later()
---
 src/rust/protover/ffi.rs      | 33 ++++++++++++++++++++++++++++++
 src/rust/protover/protover.rs | 47 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)

diff --git a/src/rust/protover/ffi.rs b/src/rust/protover/ffi.rs
index cf2e9fd78..cebf9e12f 100644
--- a/src/rust/protover/ffi.rs
+++ b/src/rust/protover/ffi.rs
@@ -101,6 +101,39 @@ pub extern "C" fn protocol_list_supports_protocol(
 }
 
 /// Provide an interface for C to translate arguments and return types for
+/// protover::list_supports_protocol_or_later
+#[no_mangle]
+pub extern "C" fn protocol_list_supports_protocol_or_later(
+    c_protocol_list: *const c_char,
+    c_protocol: uint32_t,
+    version: uint32_t,
+) -> c_int {
+    if c_protocol_list.is_null() {
+        return 1;
+    }
+
+    // Require an unsafe block to read the version from a C string. The pointer
+    // is checked above to ensure it is not null.
+    let c_str: &CStr = unsafe { CStr::from_ptr(c_protocol_list) };
+
+    let protocol_list = match c_str.to_str() {
+        Ok(n) => n,
+        Err(_) => return 1,
+    };
+
+    let protocol = match translate_to_rust(c_protocol) {
+        Ok(n) => n,
+        Err(_) => return 0,
+    };
+
+    let is_supported =
+        protover_string_supports_protocol_or_later(
+            protocol_list, protocol, version);
+
+    return if is_supported { 1 } else { 0 };
+}
+
+/// Provide an interface for C to translate arguments and return types for
 /// protover::get_supported_protocols
 #[no_mangle]
 pub extern "C" fn protover_get_supported_protocols() -> *mut c_char {
diff --git a/src/rust/protover/protover.rs b/src/rust/protover/protover.rs
index f19f7972f..85cdb3060 100644
--- a/src/rust/protover/protover.rs
+++ b/src/rust/protover/protover.rs
@@ -325,6 +325,53 @@ pub fn protover_string_supports_protocol(
     supported_versions.contains(&vers)
 }
 
+/// As protover_string_supports_protocol(), but also returns True if
+/// any later version of the protocol is supported.
+///
+/// # Examples
+/// ```
+/// use protover::*;
+///
+/// let is_supported = protover_string_supports_protocol_or_later(
+///                       "Link=3-4 Cons=5", Proto::Cons, 5);
+///
+/// assert_eq!(true, is_supported);
+///
+/// let is_supported = protover_string_supports_protocol_or_later(
+///                       "Link=3-4 Cons=5", Proto::Cons, 4);
+///
+/// assert_eq!(true, is_supported);
+///
+/// let is_supported = protover_string_supports_protocol_or_later(
+///                       "Link=3-4 Cons=5", Proto::Cons, 6);
+///
+/// assert_eq!(false, is_supported);
+/// ```
+pub fn protover_string_supports_protocol_or_later(
+    list: &str,
+    proto: Proto,
+    vers: u32,
+) -> bool {
+    let supported: HashMap<Proto, HashSet<u32>>;
+
+    match parse_protocols_from_string(list) {
+        Ok(result) => supported = result,
+        Err(_) => return false,
+    }
+
+    let supported_versions = match supported.get(&proto) {
+        Some(n) => n,
+        None => return false,
+    };
+
+    for v in supported_versions.iter() {
+        if v >= &vers {
+            return true;
+        }
+    }
+    return false;
+}
+
 /// Fully expand a version range. For example, 1-3 expands to 1,2,3
 /// Helper for get_versions
 ///



More information about the tor-commits mailing list