diff --git a/pkcs11/src/backend/login.rs b/pkcs11/src/backend/login.rs index 386fb5ea..c34b5e0a 100644 --- a/pkcs11/src/backend/login.rs +++ b/pkcs11/src/backend/login.rs @@ -7,8 +7,8 @@ use log::{debug, error, trace}; use nethsm_sdk_rs::{ apis::{self, configuration::Configuration, default_api, ResponseContent}, models::UserRole, + ureq, }; -use std::fmt::Debug; use crate::config::config_file::UserConfig; @@ -190,7 +190,7 @@ impl LoginCtx { // Try to run the api call on each instance until one succeeds pub fn try_(&mut self, api_call: F, user_mode: UserMode) -> Result where - F: FnOnce(Configuration) -> Result> + Clone, + F: FnOnce(&Configuration) -> Result> + Clone, { // we loop for a maximum of instances.len() times for _ in 0..self.instances.len() { @@ -200,7 +200,7 @@ impl LoginCtx { }; let api_call_clone = api_call.clone(); - match api_call_clone(conf) { + match api_call_clone(&conf) { Ok(result) => return Ok(result), // If the server is in an unusable state, try the next one @@ -208,8 +208,18 @@ impl LoginCtx { | Err(apis::Error::ResponseError(ResponseContent { status: 501, .. })) | Err(apis::Error::ResponseError(ResponseContent { status: 502, .. })) | Err(apis::Error::ResponseError(ResponseContent { status: 503, .. })) - | Err(apis::Error::ResponseError(ResponseContent { status: 412, .. })) => continue, - + | Err(apis::Error::ResponseError(ResponseContent { status: 412, .. })) => { + continue; + } + + Err(apis::Error::Ureq(ureq::Error::Transport(err))) => { + if matches!( + err.kind(), + ureq::ErrorKind::Io | ureq::ErrorKind::ConnectionFailed + ) { + return Err(ApiError::InstanceRemoved); + } + } // Otherwise, return the error Err(err) => return Err(err.into()), } diff --git a/pkcs11/src/backend/mod.rs b/pkcs11/src/backend/mod.rs index 9efda2b4..ee89a92d 100644 --- a/pkcs11/src/backend/mod.rs +++ b/pkcs11/src/backend/mod.rs @@ -7,9 +7,10 @@ use self::{ }; use cryptoki_sys::{ CKR_ARGUMENTS_BAD, CKR_ATTRIBUTE_VALUE_INVALID, CKR_DATA_INVALID, CKR_DATA_LEN_RANGE, - CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_ENCRYPTED_DATA_LEN_RANGE, CKR_KEY_HANDLE_INVALID, - CKR_MECHANISM_INVALID, CKR_OPERATION_ACTIVE, CKR_OPERATION_NOT_INITIALIZED, - CKR_TOKEN_NOT_PRESENT, CKR_USER_NOT_LOGGED_IN, CK_ATTRIBUTE_TYPE, CK_OBJECT_HANDLE, CK_RV, + CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_ENCRYPTED_DATA_LEN_RANGE, + CKR_KEY_HANDLE_INVALID, CKR_MECHANISM_INVALID, CKR_OPERATION_ACTIVE, + CKR_OPERATION_NOT_INITIALIZED, CKR_TOKEN_NOT_PRESENT, CKR_USER_NOT_LOGGED_IN, + CK_ATTRIBUTE_TYPE, CK_OBJECT_HANDLE, CK_RV, }; use log::error; use nethsm_sdk_rs::apis; @@ -38,6 +39,7 @@ pub enum ApiError { Serde(serde_json::Error), Io(std::io::Error), ResponseError(ResponseContent), + InstanceRemoved, NoInstance, StringParse(std::string::FromUtf8Error), } @@ -153,6 +155,7 @@ impl From for CK_RV { _ => CKR_DEVICE_ERROR, }, ApiError::StringParse(_) => CKR_DEVICE_ERROR, + ApiError::InstanceRemoved => CKR_DEVICE_REMOVED, }, } } @@ -205,6 +208,7 @@ impl std::fmt::Display for Error { _ => format!("Api error: {:?}", resp), }, ApiError::StringParse(err) => format!("String parse error: {:?}", err), + ApiError::InstanceRemoved => format!("Failed to connect to instance"), }, Error::Base64(err) => format!("Base64 Decode error: {:?}", err), Error::StringParse(err) => format!("String parse error: {:?}", err),