Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| da8c95362d | |||
| 761f970912 | |||
| 0cdefc5881 | |||
| 85454dc431 |
@@ -0,0 +1,63 @@
|
||||
name: ci-build-upload-network-monitor-agent
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-and-upload:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [arc-ubuntu-22.04]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Prepare build output directory
|
||||
shell: bash
|
||||
env:
|
||||
OUTPUT_DIR: ci-builds/${{ github.ref_name }}
|
||||
run: |
|
||||
rm -rf ci-builds || true
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
- name: Install Dependencies (Linux)
|
||||
run: sudo apt-get update && sudo apt-get -y install libudev-dev
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{ vars.REQUIRED_RUSTC_VERSION }}
|
||||
|
||||
- name: Build nym-network-monitor-agent
|
||||
shell: bash
|
||||
run: cargo build -p nym-network-monitor-agent --release
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: nym-network-monitor-agent
|
||||
path: target/release/nym-network-monitor-agent
|
||||
retention-days: 30
|
||||
|
||||
- name: Prepare build output
|
||||
shell: bash
|
||||
env:
|
||||
OUTPUT_DIR: ci-builds/${{ github.ref_name }}
|
||||
run: cp target/release/nym-network-monitor-agent "$OUTPUT_DIR"
|
||||
|
||||
- name: Deploy to CI www
|
||||
uses: easingthemes/ssh-deploy@main
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
||||
ARGS: "-avzr"
|
||||
SOURCE: "ci-builds/"
|
||||
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
||||
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
||||
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/
|
||||
EXCLUDE: "/dist/, /node_modules/"
|
||||
@@ -19,6 +19,7 @@ jobs:
|
||||
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v6
|
||||
@@ -66,11 +67,20 @@ jobs:
|
||||
--no-git-commit \
|
||||
--yes
|
||||
|
||||
- name: Commit and push version bump
|
||||
run: |
|
||||
git add -A
|
||||
git commit -m "crates release: bump version to ${{ inputs.version }}"
|
||||
git push
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: "chore/bump-version-${{ inputs.version }}"
|
||||
base: ${{ github.ref_name }}
|
||||
commit-message: "crates release: bump version to ${{ inputs.version }}"
|
||||
title: "chore: bump crate versions to ${{ inputs.version }}"
|
||||
body: |
|
||||
Automated version bump from `${{ steps.current_version.outputs.version }}` → `${{ inputs.version }}`.
|
||||
|
||||
Triggered by @${{ github.actor }} via workflow dispatch.
|
||||
labels: "automated, crates-version-bump"
|
||||
delete-branch: true
|
||||
|
||||
- name: Show package versions
|
||||
run: cargo workspaces list --long
|
||||
run: cargo workspaces list --long
|
||||
@@ -14,6 +14,7 @@ use tokio::sync::mpsc::Receiver;
|
||||
#[derive(Hash, PartialOrd, PartialEq, Clone, Debug, Eq, Copy)]
|
||||
pub enum PeerControlRequestTypeV2 {
|
||||
AddPeer,
|
||||
UpdatePeerPsk,
|
||||
RemovePeer,
|
||||
QueryPeer,
|
||||
GetClientBandwidthByKey,
|
||||
@@ -26,6 +27,7 @@ impl From<&PeerControlRequest> for PeerControlRequestTypeV2 {
|
||||
fn from(req: &PeerControlRequest) -> Self {
|
||||
match req {
|
||||
PeerControlRequest::AddPeer { .. } => PeerControlRequestTypeV2::AddPeer,
|
||||
PeerControlRequest::UpdatePeerPsk { .. } => PeerControlRequestTypeV2::UpdatePeerPsk,
|
||||
PeerControlRequest::PreAllocateIpPair { .. } => PeerControlRequestTypeV2::AddPeer,
|
||||
PeerControlRequest::RemovePeer { .. } => PeerControlRequestTypeV2::RemovePeer,
|
||||
PeerControlRequest::QueryPeer { .. } => PeerControlRequestTypeV2::QueryPeer,
|
||||
@@ -115,6 +117,15 @@ impl MockPeerControllerV2 {
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
PeerControlRequest::UpdatePeerPsk { response_tx, .. } => {
|
||||
response_tx
|
||||
.send(
|
||||
*response
|
||||
.downcast()
|
||||
.expect("registered response has mismatched type"),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
PeerControlRequest::PreAllocateIpPair { response_tx, .. } => {
|
||||
response_tx
|
||||
.send(
|
||||
|
||||
@@ -71,6 +71,7 @@ impl From<&Key> for KeyWrapper {
|
||||
#[derive(Hash, PartialOrd, PartialEq, Clone, Debug, Eq)]
|
||||
pub enum PeerControlRequestType {
|
||||
AddPeer { public_key: KeyWrapper },
|
||||
UpdatePeerPsk { peer_key: KeyWrapper },
|
||||
AllocatePeerIpPair {},
|
||||
ReleaseIpPair { ip_pair: IpPair },
|
||||
RemovePeer { key: KeyWrapper },
|
||||
@@ -86,6 +87,7 @@ impl PeerControlRequestType {
|
||||
pub fn peer_key(&self) -> Option<KeyWrapper> {
|
||||
match self {
|
||||
PeerControlRequestType::AddPeer { public_key } => Some(public_key.clone()),
|
||||
PeerControlRequestType::UpdatePeerPsk { peer_key } => Some(peer_key.clone()),
|
||||
PeerControlRequestType::AllocatePeerIpPair {} => None,
|
||||
PeerControlRequestType::ReleaseIpPair { .. } => None,
|
||||
PeerControlRequestType::RemovePeer { key } => Some(key.clone()),
|
||||
@@ -109,6 +111,11 @@ impl From<&PeerControlRequest> for PeerControlRequestType {
|
||||
PeerControlRequest::AddPeer { peer, .. } => PeerControlRequestType::AddPeer {
|
||||
public_key: (&peer.public_key).into(),
|
||||
},
|
||||
PeerControlRequest::UpdatePeerPsk { peer_key, .. } => {
|
||||
PeerControlRequestType::UpdatePeerPsk {
|
||||
peer_key: peer_key.into(),
|
||||
}
|
||||
}
|
||||
PeerControlRequest::PreAllocateIpPair { .. } => {
|
||||
PeerControlRequestType::AllocatePeerIpPair {}
|
||||
}
|
||||
@@ -271,6 +278,9 @@ impl MockPeerController {
|
||||
}
|
||||
response_tx.send_downcasted(response.content)
|
||||
}
|
||||
PeerControlRequest::UpdatePeerPsk { response_tx, .. } => {
|
||||
response_tx.send_downcasted(response.content)
|
||||
}
|
||||
PeerControlRequest::PreAllocateIpPair { response_tx, .. } => {
|
||||
response_tx.send_downcasted(response.content)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,12 @@ pub enum PeerControlRequest {
|
||||
peer: Peer,
|
||||
response_tx: oneshot::Sender<AddPeerControlResponse>,
|
||||
},
|
||||
/// Update PSK for an existing peer, without changing its IP allocation
|
||||
UpdatePeerPsk {
|
||||
peer_key: Key,
|
||||
psk: Key,
|
||||
response_tx: oneshot::Sender<UpdatePeerPskControlResponse>,
|
||||
},
|
||||
/// Attempt to allocate an IP pair from the pool
|
||||
PreAllocateIpPair {
|
||||
response_tx: oneshot::Sender<AllocatePeerControlResponse>,
|
||||
@@ -118,6 +124,7 @@ pub enum PeerControlRequest {
|
||||
}
|
||||
|
||||
pub type AddPeerControlResponse = Result<()>;
|
||||
pub type UpdatePeerPskControlResponse = Result<()>;
|
||||
pub type AllocatePeerControlResponse = Result<IpPair>;
|
||||
pub type ReleaseIpPairControlResponse = Result<()>;
|
||||
pub type RemovePeerControlResponse = Result<()>;
|
||||
@@ -317,6 +324,34 @@ impl PeerController {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_update_peer_psk_request(&mut self, peer_key: &Key, psk: Key) -> Result<()> {
|
||||
// observation will get automatically added once dropped
|
||||
let _metric_timer =
|
||||
PROMETHEUS_METRICS.start_timer(PrometheusMetric::WireguardDefguardPeerPskUpdate);
|
||||
|
||||
nym_metrics::inc!("wg_peer_update_psk_attempts");
|
||||
|
||||
let Ok(Some(mut peer)) = self.handle_query_peer_by_key(peer_key).await else {
|
||||
return Ok(());
|
||||
};
|
||||
peer.preshared_key = Some(psk);
|
||||
|
||||
// Try to update WireGuard peer
|
||||
if let Err(e) = self.wg_api.configure_peer(&peer) {
|
||||
nym_metrics::inc!("wg_peer_update_psk_failed");
|
||||
nym_metrics::inc!("wg_config_errors_total");
|
||||
return Err(e.into());
|
||||
};
|
||||
|
||||
// try to immediately update the host information, to eliminate races
|
||||
if let Ok(host_information) = self.wg_api.read_interface_data() {
|
||||
*self.host_information.write().await = host_information;
|
||||
}
|
||||
|
||||
nym_metrics::inc!("wg_peer_addition_success");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Allocate IP pair from pool for a new peer registration
|
||||
///
|
||||
/// This only allocates IPs - the caller must handle database storage and
|
||||
@@ -513,6 +548,15 @@ impl PeerController {
|
||||
PeerControlRequest::AddPeer { peer, response_tx } => {
|
||||
response_tx.send(self.handle_add_request(&peer).await).ok();
|
||||
}
|
||||
PeerControlRequest::UpdatePeerPsk {
|
||||
peer_key,
|
||||
psk,
|
||||
response_tx,
|
||||
} => {
|
||||
response_tx
|
||||
.send(self.handle_update_peer_psk_request(&peer_key, psk).await)
|
||||
.ok();
|
||||
}
|
||||
PeerControlRequest::PreAllocateIpPair { response_tx } => {
|
||||
response_tx.send(self.handle_ip_allocation_request()).ok();
|
||||
}
|
||||
|
||||
@@ -20,14 +20,12 @@ impl PeerRegistrator {
|
||||
peer: PeerPublicKey,
|
||||
psk: Key,
|
||||
) -> Result<(), GatewayWireguardError> {
|
||||
// 1. check if the peer is currently being handled
|
||||
if self.peer_manager.check_active_peer(peer).await? {
|
||||
// 2. if so, force disconnect it (as we're handling new request from the same peer)
|
||||
self.peer_manager.remove_peer(peer).await?;
|
||||
}
|
||||
|
||||
// 3. update the on-disk PSK
|
||||
let encoded_psk = psk.to_lower_hex();
|
||||
|
||||
// 1. update the PSK in the active configuration
|
||||
self.peer_manager.update_peer_psk(peer, psk).await?;
|
||||
|
||||
// 2. update the on-disk PSK
|
||||
self.ecash_verifier
|
||||
.storage()
|
||||
.update_peer_psk(&peer.to_string(), Some(&encoded_psk))
|
||||
|
||||
@@ -125,6 +125,44 @@ impl PeerManager {
|
||||
res
|
||||
}
|
||||
|
||||
pub async fn update_peer_psk(
|
||||
&self,
|
||||
pub_key: PeerPublicKey,
|
||||
psk: Key,
|
||||
) -> Result<(), GatewayWireguardError> {
|
||||
let controller_start = Instant::now();
|
||||
let peer_key = Key::new(pub_key.to_bytes());
|
||||
let (response_tx, response_rx) = oneshot::channel();
|
||||
let msg = PeerControlRequest::UpdatePeerPsk {
|
||||
peer_key,
|
||||
psk,
|
||||
response_tx,
|
||||
};
|
||||
self.wireguard_gateway_data
|
||||
.peer_tx()
|
||||
.send(msg)
|
||||
.await
|
||||
.map_err(|_| GatewayWireguardError::PeerInteractionStopped)?;
|
||||
|
||||
let res = response_rx
|
||||
.await
|
||||
.map_err(|_| GatewayWireguardError::internal("no response for update peer psk"))?
|
||||
.map_err(|err| {
|
||||
GatewayWireguardError::InternalError(format!(
|
||||
"updating peer psk could not be performed: {err:?}"
|
||||
))
|
||||
});
|
||||
|
||||
let latency = controller_start.elapsed().as_secs_f64();
|
||||
add_histogram_obs!(
|
||||
"wg_peer_controller_channel_latency_seconds",
|
||||
latency,
|
||||
WG_CONTROLLER_LATENCY_BUCKETS
|
||||
);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub async fn remove_peer(&self, pub_key: PeerPublicKey) -> Result<(), GatewayWireguardError> {
|
||||
let controller_start = Instant::now();
|
||||
let key = Key::new(pub_key.to_bytes());
|
||||
|
||||
@@ -157,6 +157,9 @@ pub enum PrometheusMetric {
|
||||
#[strum(props(help = "The distribution of defguard peer creation time"))]
|
||||
WireguardDefguardPeerCreation,
|
||||
|
||||
#[strum(props(help = "The distribution of defguard peer psk update time"))]
|
||||
WireguardDefguardPeerPskUpdate,
|
||||
|
||||
#[strum(props(
|
||||
help = "The distribution of time it takes to verify a credential during peer registration"
|
||||
))]
|
||||
@@ -320,6 +323,9 @@ impl PrometheusMetric {
|
||||
PrometheusMetric::WireguardDefguardPeerCreation => {
|
||||
Metric::new_histogram(&name, help, Some(REG_LATENCY_BUCKETS))
|
||||
}
|
||||
PrometheusMetric::WireguardDefguardPeerPskUpdate => {
|
||||
Metric::new_histogram(&name, help, Some(REG_LATENCY_BUCKETS))
|
||||
}
|
||||
PrometheusMetric::DvpnAuthenticatorClientRegistrationMsg1 => {
|
||||
Metric::new_histogram(&name, help, Some(REG_LATENCY_BUCKETS))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user