further propagation of key rotation information
This commit is contained in:
@@ -16,7 +16,6 @@ use nym_node_requests::api::v1::mixnode::models::Mixnode;
|
||||
use nym_node_requests::api::v1::network_requester::exit_policy::models::UsedExitPolicy;
|
||||
use nym_node_requests::api::v1::network_requester::models::NetworkRequester;
|
||||
use nym_node_requests::api::v1::node::models::{AuxiliaryDetails, HostSystem, NodeDescription};
|
||||
use nym_node_requests::api::SignedHostInformation;
|
||||
use nym_node_requests::routes;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::Path;
|
||||
|
||||
@@ -28,33 +28,33 @@ impl ActiveSphinxKeys {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn even(&self) -> Option<impl Deref<Target = SphinxPrivateKey>> {
|
||||
pub(crate) fn even(&self) -> Option<SphinxKeyGuard> {
|
||||
let primary = self.inner.primary_key.load();
|
||||
if primary.is_even_rotation() {
|
||||
return Some(primary);
|
||||
return Some(SphinxKeyGuard::Primary(primary));
|
||||
}
|
||||
self.secondary()
|
||||
}
|
||||
|
||||
pub(crate) fn odd(&self) -> Option<impl Deref<Target = SphinxPrivateKey>> {
|
||||
pub(crate) fn odd(&self) -> Option<SphinxKeyGuard> {
|
||||
let primary = self.inner.primary_key.load();
|
||||
if !primary.is_even_rotation() {
|
||||
return Some(primary);
|
||||
return Some(SphinxKeyGuard::Primary(primary));
|
||||
}
|
||||
self.secondary()
|
||||
}
|
||||
|
||||
pub(crate) fn primary(&self) -> impl Deref<Target = SphinxPrivateKey> {
|
||||
self.inner.primary_key.map(|k: &SphinxPrivateKey| k).load()
|
||||
pub(crate) fn primary(&self) -> SphinxKeyGuard {
|
||||
SphinxKeyGuard::Primary(self.inner.primary_key.load())
|
||||
}
|
||||
|
||||
pub(crate) fn secondary(&self) -> Option<impl Deref<Target = SphinxPrivateKey>> {
|
||||
pub(crate) fn secondary(&self) -> Option<SphinxKeyGuard> {
|
||||
let guard = self.inner.secondary_key.load();
|
||||
if guard.is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(SecondaryKeyGuard { guard })
|
||||
Some(SphinxKeyGuard::Secondary(SecondaryKeyGuard { guard }))
|
||||
}
|
||||
|
||||
// 1. generate new key
|
||||
@@ -87,6 +87,23 @@ impl ActiveSphinxKeys {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum SphinxKeyGuard {
|
||||
// Primary(Guard<Arc<SphinxPrivateKey>>),
|
||||
Primary(Guard<Arc<SphinxPrivateKey>>),
|
||||
Secondary(SecondaryKeyGuard),
|
||||
}
|
||||
|
||||
impl Deref for SphinxKeyGuard {
|
||||
type Target = SphinxPrivateKey;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
SphinxKeyGuard::Primary(g) => g.deref(),
|
||||
SphinxKeyGuard::Secondary(g) => g.deref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct SecondaryKeyGuard {
|
||||
guard: Guard<Option<Arc<SphinxPrivateKey>>>,
|
||||
}
|
||||
|
||||
@@ -32,6 +32,10 @@ impl SphinxPrivateKey {
|
||||
self.inner.public_key()
|
||||
}
|
||||
|
||||
pub(crate) fn inner(&self) -> &x25519::PrivateKey {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub(crate) fn is_even_rotation(&self) -> bool {
|
||||
self.rotation_id & 1 == 0
|
||||
}
|
||||
|
||||
@@ -223,11 +223,15 @@ impl ConnectionHandler {
|
||||
SphinxKeyRotation::Unknown => {
|
||||
// we have to try both keys, start with the primary as it has higher likelihood of being correct
|
||||
// if let Ok(partially_unwrapped) = PartiallyUnwrappedPacket::new()
|
||||
match PartiallyUnwrappedPacket::new(packet, self.shared.sphinx_keys.primary()) {
|
||||
match PartiallyUnwrappedPacket::new(
|
||||
packet,
|
||||
self.shared.sphinx_keys.primary().inner().as_ref(),
|
||||
) {
|
||||
Ok(unwrapped_packet) => Ok(unwrapped_packet),
|
||||
Err((packet, err)) => {
|
||||
if let Some(secondary) = self.shared.sphinx_keys.secondary() {
|
||||
PartiallyUnwrappedPacket::new(packet, secondary).map_err(|(_, err)| err)
|
||||
PartiallyUnwrappedPacket::new(packet, secondary.inner().as_ref())
|
||||
.map_err(|(_, err)| err)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
@@ -238,13 +242,15 @@ impl ConnectionHandler {
|
||||
let Some(odd_key) = self.shared.sphinx_keys.odd() else {
|
||||
return Err(PacketProcessingError::ExpiredKey);
|
||||
};
|
||||
PartiallyUnwrappedPacket::new(packet, odd_key).map_err(|(_, err)| err)
|
||||
PartiallyUnwrappedPacket::new(packet, odd_key.inner().as_ref())
|
||||
.map_err(|(_, err)| err)
|
||||
}
|
||||
SphinxKeyRotation::EvenRotation => {
|
||||
let Some(even_key) = self.shared.sphinx_keys.even() else {
|
||||
return Err(PacketProcessingError::ExpiredKey);
|
||||
};
|
||||
PartiallyUnwrappedPacket::new(packet, even_key).map_err(|(_, err)| err)
|
||||
PartiallyUnwrappedPacket::new(packet, even_key.inner().as_ref())
|
||||
.map_err(|(_, err)| err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,19 +391,19 @@ impl ConnectionHandler {
|
||||
// and by the time we need it, the rotation info should be present)
|
||||
match packet.header().key_rotation {
|
||||
SphinxKeyRotation::Unknown => {
|
||||
process_framed_packet(packet, self.shared.sphinx_keys.primary())
|
||||
process_framed_packet(packet, self.shared.sphinx_keys.primary().inner().as_ref())
|
||||
}
|
||||
SphinxKeyRotation::OddRotation => {
|
||||
let Some(odd_key) = self.shared.sphinx_keys.odd() else {
|
||||
return Err(PacketProcessingError::ExpiredKey);
|
||||
};
|
||||
process_framed_packet(packet, odd_key)
|
||||
process_framed_packet(packet, odd_key.inner().as_ref())
|
||||
}
|
||||
SphinxKeyRotation::EvenRotation => {
|
||||
let Some(even_key) = self.shared.sphinx_keys.even() else {
|
||||
return Err(PacketProcessingError::ExpiredKey);
|
||||
};
|
||||
process_framed_packet(packet, even_key)
|
||||
process_framed_packet(packet, even_key.inner().as_ref())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,32 +58,20 @@ impl<C, F> PacketForwarder<C, F> {
|
||||
C: SendWithoutResponse,
|
||||
F: RoutingFilter,
|
||||
{
|
||||
let next_hop = packet.next_hop();
|
||||
let next_hop = packet.next_hop_address();
|
||||
|
||||
let packet_type = packet.packet_type();
|
||||
let packet = packet.into_packet();
|
||||
|
||||
if let Err(err) = self
|
||||
.mixnet_client
|
||||
.send_without_response(next_hop, packet, packet_type)
|
||||
{
|
||||
if let Err(err) = self.mixnet_client.send_without_response(packet) {
|
||||
if err.kind() == io::ErrorKind::WouldBlock {
|
||||
// we only know for sure if we dropped a packet if our sending queue was full
|
||||
// in any other case the connection might still be re-established (or created for the first time)
|
||||
// and the packet might get sent, but we won't know about it
|
||||
self.metrics
|
||||
.mixnet
|
||||
.egress_dropped_forward_packet(next_hop.into())
|
||||
self.metrics.mixnet.egress_dropped_forward_packet(next_hop)
|
||||
} else if err.kind() == io::ErrorKind::NotConnected {
|
||||
// let's give the benefit of the doubt and assume we manage to establish connection
|
||||
self.metrics
|
||||
.mixnet
|
||||
.egress_sent_forward_packet(next_hop.into())
|
||||
self.metrics.mixnet.egress_sent_forward_packet(next_hop)
|
||||
}
|
||||
} else {
|
||||
self.metrics
|
||||
.mixnet
|
||||
.egress_sent_forward_packet(next_hop.into())
|
||||
self.metrics.mixnet.egress_sent_forward_packet(next_hop)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user