From fe246049a78a28e622bc29f3ded1608cb858314e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Wed, 4 Sep 2024 17:57:13 +0200 Subject: [PATCH] Share instance configuration accross login contexts --- pkcs11/src/backend/login.rs | 6 +- pkcs11/src/config/device.rs | 2 +- pkcs11/src/config/initialization.rs | 166 ++++++++++++++-------------- 3 files changed, 89 insertions(+), 85 deletions(-) diff --git a/pkcs11/src/backend/login.rs b/pkcs11/src/backend/login.rs index c885f43e..4a30aa02 100644 --- a/pkcs11/src/backend/login.rs +++ b/pkcs11/src/backend/login.rs @@ -9,7 +9,7 @@ use nethsm_sdk_rs::{ models::UserRole, ureq, }; -use std::{thread, time::Duration}; +use std::{sync::Arc, thread, time::Duration}; use crate::config::config_file::{RetryConfig, UserConfig}; @@ -19,7 +19,7 @@ use super::{ApiError, Error}; pub struct LoginCtx { operator: Option, administrator: Option, - instances: Vec, + instances: Arc<[Configuration]>, index: usize, ck_state: CK_STATE, retries: Option, @@ -65,7 +65,7 @@ impl LoginCtx { pub fn new( operator: Option, administrator: Option, - instances: Vec, + instances: Arc<[Configuration]>, retries: Option, ) -> Self { let mut ck_state = CKS_RO_PUBLIC_SESSION; diff --git a/pkcs11/src/config/device.rs b/pkcs11/src/config/device.rs index cffb6879..c14dbe08 100644 --- a/pkcs11/src/config/device.rs +++ b/pkcs11/src/config/device.rs @@ -18,7 +18,7 @@ pub struct Slot { pub label: String, pub retries: Option, pub _description: Option, - pub instances: Vec, + pub instances: Arc<[Configuration]>, pub operator: Option, pub administrator: Option, pub db: Arc<(Mutex, Condvar)>, diff --git a/pkcs11/src/config/initialization.rs b/pkcs11/src/config/initialization.rs index 44ae6e82..b156b824 100644 --- a/pkcs11/src/config/initialization.rs +++ b/pkcs11/src/config/initialization.rs @@ -188,8 +188,6 @@ impl ServerCertVerifier for FingerprintVerifier { } fn slot_from_config(slot: &SlotConfig) -> Result { - let mut instances = vec![]; - let default_user = slot .operator .as_ref() @@ -203,88 +201,94 @@ fn slot_from_config(slot: &SlotConfig) -> Result { slot.retries ); - for instance in slot.instances.iter() { - let tls_conf = rustls::ClientConfig::builder(); - - let tls_conf = if instance.danger_insecure_cert { - tls_conf - .dangerous() - .with_custom_certificate_verifier(Arc::new(DangerIgnoreVerifier)) - .with_no_client_auth() - } else if !instance.sha256_fingerprints.is_empty() { - let fingerprints = instance - .sha256_fingerprints - .iter() - .map(|f| f.value.clone()) - .collect(); - tls_conf - .dangerous() - .with_custom_certificate_verifier(Arc::new(FingerprintVerifier { fingerprints })) - .with_no_client_auth() - } else { - let mut roots = rustls::RootCertStore::empty(); - let native_certs = rustls_native_certs::load_native_certs().map_err(|err| { - error!("Failed to load certificates: {err}"); - InitializationError::NoCerts - })?; - - let (added, failed) = roots.add_parsable_certificates(native_certs); - // panic!("{:?}", (added, failed)); - debug!("Added {added} certifcates and failed to parse {failed} certificates"); - - if added == 0 { - error!("Added no native certificates"); - return Err(InitializationError::NoCerts); + let instances = slot + .instances + .iter() + .map(|instance| { + let tls_conf = rustls::ClientConfig::builder(); + + let tls_conf = if instance.danger_insecure_cert { + tls_conf + .dangerous() + .with_custom_certificate_verifier(Arc::new(DangerIgnoreVerifier)) + .with_no_client_auth() + } else if !instance.sha256_fingerprints.is_empty() { + let fingerprints = instance + .sha256_fingerprints + .iter() + .map(|f| f.value.clone()) + .collect(); + tls_conf + .dangerous() + .with_custom_certificate_verifier(Arc::new(FingerprintVerifier { + fingerprints, + })) + .with_no_client_auth() + } else { + let mut roots = rustls::RootCertStore::empty(); + let native_certs = rustls_native_certs::load_native_certs().map_err(|err| { + error!("Failed to load certificates: {err}"); + InitializationError::NoCerts + })?; + + let (added, failed) = roots.add_parsable_certificates(native_certs); + // panic!("{:?}", (added, failed)); + debug!("Added {added} certifcates and failed to parse {failed} certificates"); + + if added == 0 { + error!("Added no native certificates"); + return Err(InitializationError::NoCerts); + } + + tls_conf.with_root_certificates(roots).with_no_client_auth() + }; + + info!( + "Instance configured with: max_idle_connection: {:?}", + instance.max_idle_connections + ); + + let max_idle_connections = instance + .max_idle_connections + .or_else(|| available_parallelism().ok().map(Into::into)) + .unwrap_or(100); + + // 100 idle connections is the default + // By default there is 1 idle connection per host, but we are only connecting to 1 host. + // So we need to allow the connection pool to scale to match the number of threads + let mut builder = ureq::AgentBuilder::new() + .tls_config(Arc::new(tls_conf)) + .max_idle_connections(max_idle_connections) + .max_idle_connections_per_host(max_idle_connections); + + if let Some(t) = slot.timeout_seconds { + builder = builder + .timeout(Duration::from_secs(t)) + .timeout_connect(Duration::from_secs(10)); + } + if let Some(keepalive) = slot.tcp_keepalive { + builder = builder + .tcp_keepalive_time(Duration::from_secs(keepalive.time_seconds)) + .tcp_keepalive_interval(Duration::from_secs(keepalive.interval_seconds)) + .tcp_keepalive_retries(keepalive.retries); } - tls_conf.with_root_certificates(roots).with_no_client_auth() - }; - - info!( - "Instance configured with: max_idle_connection: {:?}", - instance.max_idle_connections - ); - - let max_idle_connections = instance - .max_idle_connections - .or_else(|| available_parallelism().ok().map(Into::into)) - .unwrap_or(100); - - // 100 idle connections is the default - // By default there is 1 idle connection per host, but we are only connecting to 1 host. - // So we need to allow the connection pool to scale to match the number of threads - let mut builder = ureq::AgentBuilder::new() - .tls_config(Arc::new(tls_conf)) - .max_idle_connections(max_idle_connections) - .max_idle_connections_per_host(max_idle_connections); - - if let Some(t) = slot.timeout_seconds { - builder = builder - .timeout(Duration::from_secs(t)) - .timeout_connect(Duration::from_secs(10)); - } - if let Some(keepalive) = slot.tcp_keepalive { - builder = builder - .tcp_keepalive_time(Duration::from_secs(keepalive.time_seconds)) - .tcp_keepalive_interval(Duration::from_secs(keepalive.interval_seconds)) - .tcp_keepalive_retries(keepalive.retries); - } - - if let Some(max_idle_duration) = slot.connections_max_idle_duration { - builder = builder.max_idle_duration(Duration::from_secs(max_idle_duration)); - } - - let agent = builder.build(); + if let Some(max_idle_duration) = slot.connections_max_idle_duration { + builder = builder.max_idle_duration(Duration::from_secs(max_idle_duration)); + } - let api_config = nethsm_sdk_rs::apis::configuration::Configuration { - client: agent, - base_path: instance.url.clone(), - basic_auth: Some((default_user.username.clone(), default_user.password.clone())), - user_agent: Some(DEFAULT_USER_AGENT.to_string()), - ..Default::default() - }; - instances.push(api_config); - } + let agent = builder.build(); + + let api_config = nethsm_sdk_rs::apis::configuration::Configuration { + client: agent, + base_path: instance.url.clone(), + basic_auth: Some((default_user.username.clone(), default_user.password.clone())), + user_agent: Some(DEFAULT_USER_AGENT.to_string()), + ..Default::default() + }; + Ok(api_config) + }) + .collect::>()?; Ok(Slot { _description: slot.description.clone(),