Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion common/wireguard/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ time = { workspace = true }
tracing = { workspace = true }

nym-authenticator-requests = { path = "../authenticator-requests" }
nym-credentials-interface = { path = "../credentials-interface" }
nym-credential-verification = { path = "../credential-verification" }
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
nym-gateway-storage = { path = "../gateway-storage" }
nym-gateway-requests = { path = "../gateway-requests" }
nym-network-defaults = { path = "../network-defaults" }
nym-task = { path = "../task" }
nym-wireguard-types = { path = "../wireguard-types" }
Expand All @@ -46,4 +48,3 @@ nym-gateway-storage = { path = "../gateway-storage", features = ["mock"] }
[features]
default = []
mock = ["nym-gateway-storage/mock"]

11 changes: 6 additions & 5 deletions common/wireguard/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
// #![warn(clippy::unwrap_used)]

use defguard_wireguard_rs::{host::Peer, key::Key, net::IpAddrMask, WGApi, WireguardInterfaceApi};
use nym_crypto::asymmetric::x25519::KeyPair;
#[cfg(target_os = "linux")]
use nym_gateway_storage::GatewayStorage;
use nym_credential_verification::ecash::EcashManager;
use nym_crypto::asymmetric::x25519::KeyPair;
use nym_wireguard_types::Config;
use peer_controller::PeerControlRequest;
use std::sync::Arc;
Expand Down Expand Up @@ -158,7 +158,7 @@ pub struct WireguardData {
/// Start wireguard device
#[cfg(target_os = "linux")]
pub async fn start_wireguard(
storage: GatewayStorage,
ecash_manager: Arc<EcashManager>,
metrics: nym_node_metrics::NymNodeMetrics,
peers: Vec<Peer>,
task_client: nym_task::TaskClient,
Expand All @@ -167,6 +167,7 @@ pub async fn start_wireguard(
use base64::{prelude::BASE64_STANDARD, Engine};
use defguard_wireguard_rs::{InterfaceConfiguration, WireguardInterfaceApi};
use ip_network::IpNetwork;
use nym_credential_verification::ecash::traits::EcashManager;
use peer_controller::PeerController;
use std::collections::HashMap;
use tokio::sync::RwLock;
Expand All @@ -178,7 +179,7 @@ pub async fn start_wireguard(

for peer in peers.iter() {
let bandwidth_manager = Arc::new(RwLock::new(
PeerController::generate_bandwidth_manager(Box::new(storage.clone()), &peer.public_key)
PeerController::generate_bandwidth_manager(ecash_manager.storage(), &peer.public_key)
.await?,
));
peer_bandwidth_managers.insert(peer.public_key.clone(), (bandwidth_manager, peer.clone()));
Expand Down Expand Up @@ -233,7 +234,7 @@ pub async fn start_wireguard(
let host = wg_api.read_interface_data()?;
let wg_api = std::sync::Arc::new(WgApiWrapper::new(wg_api));
let mut controller = PeerController::new(
Box::new(storage),
ecash_manager,
metrics,
wg_api.clone(),
host,
Expand Down
81 changes: 68 additions & 13 deletions common/wireguard/src/peer_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ use defguard_wireguard_rs::{
use futures::channel::oneshot;
use log::info;
use nym_credential_verification::{
bandwidth_storage_manager::BandwidthStorageManager, BandwidthFlushingBehaviourConfig,
ClientBandwidth,
bandwidth_storage_manager::BandwidthStorageManager, ecash::traits::EcashManager,
BandwidthFlushingBehaviourConfig, ClientBandwidth, CredentialVerifier,
};
use nym_credentials_interface::CredentialSpendingData;
use nym_gateway_requests::models::CredentialSpendingRequest;
use nym_gateway_storage::traits::BandwidthGatewayStorage;
use nym_node_metrics::NymNodeMetrics;
use nym_wireguard_types::DEFAULT_PEER_TIMEOUT_CHECK;
Expand Down Expand Up @@ -40,6 +42,11 @@ pub enum PeerControlRequest {
key: Key,
response_tx: oneshot::Sender<GetClientBandwidthControlResponse>,
},
GetVerifier {
key: Key,
credential: Box<CredentialSpendingData>,
response_tx: oneshot::Sender<QueryVerifierControlResponse>,
},
}

pub struct AddPeerControlResponse {
Expand All @@ -59,8 +66,13 @@ pub struct GetClientBandwidthControlResponse {
pub client_bandwidth: Option<ClientBandwidth>,
}

pub struct QueryVerifierControlResponse {
pub success: bool,
pub verifier: Option<CredentialVerifier>,
}

pub struct PeerController {
storage: Box<dyn BandwidthGatewayStorage + Send + Sync>,
ecash_verifier: Arc<dyn EcashManager + Send + Sync>,

// we have "all" metrics of a node, but they're behind a single Arc pointer,
// so the overhead is minimal
Expand All @@ -79,7 +91,7 @@ pub struct PeerController {
impl PeerController {
#[allow(clippy::too_many_arguments)]
pub fn new(
storage: Box<dyn BandwidthGatewayStorage + Send + Sync>,
ecash_verifier: Arc<dyn EcashManager + Send + Sync>,
metrics: NymNodeMetrics,
wg_api: Arc<dyn WireguardInterfaceApi + Send + Sync>,
initial_host_information: Host,
Expand Down Expand Up @@ -114,7 +126,7 @@ impl PeerController {
.collect();

PeerController {
storage,
ecash_verifier,
wg_api,
host_information,
bw_storage_managers,
Expand All @@ -128,7 +140,10 @@ impl PeerController {

// Function that should be used for peer removal, to handle both storage and kernel interaction
pub async fn remove_peer(&mut self, key: &Key) -> Result<(), Error> {
self.storage.remove_wireguard_peer(&key.to_string()).await?;
self.ecash_verifier
.storage()
.remove_wireguard_peer(&key.to_string())
.await?;
self.bw_storage_managers.remove(key);
let ret = self.wg_api.remove_peer(key);
if ret.is_err() {
Expand Down Expand Up @@ -164,11 +179,8 @@ impl PeerController {
async fn handle_add_request(&mut self, peer: &Peer) -> Result<(), Error> {
self.wg_api.configure_peer(peer)?;
let bandwidth_storage_manager = Arc::new(RwLock::new(
Self::generate_bandwidth_manager(
dyn_clone::clone_box(&*self.storage),
&peer.public_key,
)
.await?,
Self::generate_bandwidth_manager(self.ecash_verifier.storage(), &peer.public_key)
.await?,
));
let cached_peer_manager = CachedPeerManager::new(peer);
let mut handle = PeerHandle::new(
Expand All @@ -195,7 +207,8 @@ impl PeerController {

async fn handle_query_peer(&self, key: &Key) -> Result<Option<Peer>, Error> {
Ok(self
.storage
.ecash_verifier
.storage()
.get_wireguard_peer(&key.to_string())
.await?
.map(Peer::try_from)
Expand All @@ -210,6 +223,35 @@ impl PeerController {
}
}

async fn handle_query_verifier(
&self,
key: &Key,
credential: CredentialSpendingData,
) -> Result<CredentialVerifier, Error> {
let storage = self.ecash_verifier.storage();
let client_id = storage
.get_wireguard_peer(&key.to_string())
.await?
.ok_or(Error::MissingClientBandwidthEntry)?
.client_id;
let Some(bandwidth_storage_manager) = self.bw_storage_managers.get(key) else {
return Err(Error::MissingClientBandwidthEntry);
};
let client_bandwidth = bandwidth_storage_manager.read().await.client_bandwidth();
let verifier = CredentialVerifier::new(
CredentialSpendingRequest::new(credential),
self.ecash_verifier.clone(),
BandwidthStorageManager::new(
storage,
client_bandwidth,
client_id,
BandwidthFlushingBehaviourConfig::default(),
true,
),
);
Ok(verifier)
}

async fn update_metrics(&self, new_host: &Host) {
let now = SystemTime::now();
const ACTIVITY_THRESHOLD: Duration = Duration::from_secs(180);
Expand Down Expand Up @@ -327,6 +369,14 @@ impl PeerController {
let client_bandwidth = self.handle_get_client_bandwidth(&key).await;
response_tx.send(GetClientBandwidthControlResponse { client_bandwidth }).ok();
}
Some(PeerControlRequest::GetVerifier { key, credential, response_tx }) => {
let ret = self.handle_query_verifier(&key, *credential).await;
if let Ok(verifier) = ret {
response_tx.send(QueryVerifierControlResponse { success: true, verifier: Some(verifier) }).ok();
} else {
response_tx.send(QueryVerifierControlResponse { success: false, verifier: None }).ok();
}
}
None => {
log::trace!("PeerController [main loop]: stopping since channel closed");
break;
Expand Down Expand Up @@ -433,13 +483,18 @@ pub fn start_controller(
Arc<RwLock<nym_gateway_storage::traits::mock::MockGatewayStorage>>,
nym_task::TaskManager,
) {
use std::sync::Arc;

let storage = Arc::new(RwLock::new(
nym_gateway_storage::traits::mock::MockGatewayStorage::default(),
));
let ecash_manager = Arc::new(nym_credential_verification::ecash::MockEcashManager::new(
Box::new(storage.clone()),
));
let wg_api = Arc::new(MockWgApi::default());
let task_manager = nym_task::TaskManager::default();
let mut peer_controller = PeerController::new(
Box::new(storage.clone()),
ecash_manager,
Default::default(),
wg_api,
Default::default(),
Expand Down
8 changes: 7 additions & 1 deletion gateway/src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,14 @@ impl GatewayTasksBuilder {
);
};

let Some(ecash_manager) = self.ecash_manager.clone() else {
return Err(
GatewayError::InternalWireguardError("ecash manager not set".to_string()).into(),
);
};

let wg_handle = nym_wireguard::start_wireguard(
self.storage.clone(),
ecash_manager,
self.metrics.clone(),
all_peers,
self.shutdown.fork("wireguard"),
Expand Down
1 change: 0 additions & 1 deletion nym-node/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::cli::commands::{
test_throughput,
};
use crate::env::vars::{NYMNODE_CONFIG_ENV_FILE_ARG, NYMNODE_NO_BANNER_ARG};
use crate::logging::setup_tracing_logger;
use clap::{Args, Parser, Subcommand};
use nym_bin_common::bin_info;
use std::future::Future;
Expand Down
37 changes: 10 additions & 27 deletions service-providers/authenticator/src/mixnet_listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,38 +691,21 @@ impl MixnetListener {
request_id: u64,
reply_to: Option<Recipient>,
) -> AuthenticatorHandleResult {
let client_id = self
.ecash_verifier
.storage()
.get_wireguard_peer(&msg.pub_key().to_string())
.await?
.ok_or(AuthenticatorError::MissingClientBandwidthEntry)?
.client_id;
let client_bandwidth = self
.peer_manager
.query_client_bandwidth(msg.pub_key())
.await?
.ok_or(AuthenticatorError::MissingClientBandwidthEntry)?;

let available_bandwidth = if self.received_retry(msg.as_ref()) {
// don't process the credential and just return the current bandwidth
client_bandwidth.available().await
self.peer_manager
.query_bandwidth(msg.pub_key())
.await?
.ok_or(AuthenticatorError::MissingClientBandwidthEntry)?
} else {
let credential = msg.credential();
let mut verifier = CredentialVerifier::new(
CredentialSpendingRequest::new(credential.clone()),
self.ecash_verifier.clone(),
BandwidthStorageManager::new(
self.ecash_verifier.storage(),
client_bandwidth,
client_id,
BandwidthFlushingBehaviourConfig::default(),
true,
),
);
let mut verifier = self
.peer_manager
.query_verifier(msg.pub_key(), msg.credential())
.await?
.ok_or(AuthenticatorError::MissingClientBandwidthEntry)?;
let available_bandwidth = verifier.verify().await?;
self.seen_credential_cache
.insert_credential(credential, msg.pub_key());
.insert_credential(msg.credential(), msg.pub_key());
available_bandwidth
};

Expand Down
Loading
Loading