summaryrefslogtreecommitdiffhomepage
path: root/talpid-core
diff options
context:
space:
mode:
authorEmīls <emils@mullvad.net>2018-06-26 15:12:56 +0100
committerEmīls <emils@mullvad.net>2018-06-27 11:42:42 +0100
commit6e8c2ff7a8618426faed87dc6d753e96fe682f41 (patch)
tree6f33ea3a36d25383e900b2efd82a3681d18f6095 /talpid-core
parent63cccc6a0cfbab34a46c9904cf4a679efbc9f0c2 (diff)
downloadmullvadvpn-6e8c2ff7a8618426faed87dc6d753e96fe682f41.tar.xz
mullvadvpn-6e8c2ff7a8618426faed87dc6d753e96fe682f41.zip
Improve FFI error returning
Diffstat (limited to 'talpid-core')
-rw-r--r--talpid-core/src/firewall/windows/route.rs46
1 files changed, 33 insertions, 13 deletions
diff --git a/talpid-core/src/firewall/windows/route.rs b/talpid-core/src/firewall/windows/route.rs
index c66dfbfabd..6ecf336956 100644
--- a/talpid-core/src/firewall/windows/route.rs
+++ b/talpid-core/src/firewall/windows/route.rs
@@ -9,35 +9,55 @@ error_chain!{
MetricApplication{
description("Failed to set the metrics for a network interface")
}
+ InvalidInterfaceAlias{
+ description("Supplied interface alias is invalid")
+ }
}
}
-// Returns true if metrics were changed, false otherwise
+/// Returns true if metrics were changed, false otherwise
pub fn ensure_top_metric_for_interface(interface_alias: &str) -> Result<bool> {
let interface_alias_ws =
- WideCString::new(interface_alias.encode_utf16().collect::<Vec<_>>()).unwrap();
- match unsafe {
+ WideCString::from_str(interface_alias).chain_err(|| ErrorKind::InvalidInterfaceAlias)?;
+ unsafe {
WinRoute_EnsureTopMetric(
interface_alias_ws.as_wide_c_str().as_ptr(),
Some(ffi::error_sink),
ptr::null_mut(),
- )
- } {
- 0 => Ok(false),
- 1 => Ok(true),
- -1 => Err(Error::from(ErrorKind::MetricApplication)),
- _ => {
- error!("Unexpected return code from WinRoute_EnsureTopMetric");
- Err(Error::from(ErrorKind::MetricApplication))
+ ).into()
+ }
+}
+
+// Allowing dead code here as this type should only ever be constructed by an
+// FFI function.
+#[allow(dead_code)]
+#[repr(u32)]
+enum MetricResult {
+ MetricsUnchanged = 0u32,
+ MetricsChanged = 1u32,
+ Failure = 2u32,
+ UnexpectedValue,
+}
+
+impl Into<Result<bool>> for MetricResult {
+ fn into(self) -> Result<bool> {
+ match self {
+ MetricResult::MetricsUnchanged => Ok(false),
+ MetricResult::MetricsChanged => Ok(true),
+ MetricResult::Failure => Err(Error::from(ErrorKind::MetricApplication)),
+ MetricResult::UnexpectedValue => {
+ error!("Unexpected return code from WinRoute_EnsureTopMetric");
+ Err(Error::from(ErrorKind::MetricApplication))
+ }
}
}
}
extern "system" {
#[link_name(WinRoute_EnsureTopMetric)]
- pub fn WinRoute_EnsureTopMetric(
+ fn WinRoute_EnsureTopMetric(
tunnel_interface_alias: *const libc::wchar_t,
sink: Option<ffi::ErrorSink>,
sink_context: *mut libc::c_void,
- ) -> i32;
+ ) -> MetricResult;
}