Simplify IPR v8 (#5532)
* Purge stuff from v8 * Adapt to v8 changes * Use protocol in ipr header * Remove commented out code * Remove unused error
This commit is contained in:
Generated
+4
@@ -5913,6 +5913,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"nym-bin-common",
|
||||
"nym-crypto",
|
||||
"nym-service-provider-requests-common",
|
||||
"nym-sphinx",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
@@ -5944,6 +5945,7 @@ dependencies = [
|
||||
"nym-network-defaults",
|
||||
"nym-network-requester",
|
||||
"nym-sdk",
|
||||
"nym-service-provider-requests-common",
|
||||
"nym-service-providers-common",
|
||||
"nym-sphinx",
|
||||
"nym-task",
|
||||
@@ -6517,7 +6519,9 @@ dependencies = [
|
||||
name = "nym-service-provider-requests-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"serde",
|
||||
"thiserror 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -13,6 +13,7 @@ bincode = { workspace = true }
|
||||
bytes = { workspace = true }
|
||||
nym-bin-common = { path = "../bin-common" }
|
||||
nym-crypto = { path = "../crypto" }
|
||||
nym-service-provider-requests-common = { path = "../service-provider-requests-common" }
|
||||
nym-sphinx = { path = "../nymsphinx" }
|
||||
rand = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
use std::{fmt, sync::Arc};
|
||||
use std::fmt;
|
||||
|
||||
use nym_crypto::asymmetric::ed25519;
|
||||
use nym_sphinx::addressing::Recipient;
|
||||
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use crate::{
|
||||
sign::{SignatureError, SignedRequest},
|
||||
IpPair,
|
||||
};
|
||||
|
||||
use super::VERSION;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct IpPacketRequest {
|
||||
pub version: u8,
|
||||
pub protocol: Protocol,
|
||||
pub data: IpPacketRequestData,
|
||||
}
|
||||
|
||||
@@ -26,9 +20,8 @@ pub enum IpPacketRequestData {
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub enum ControlRequest {
|
||||
StaticConnect(SignedStaticConnectRequest),
|
||||
DynamicConnect(SignedDynamicConnectRequest),
|
||||
Disconnect(SignedDisconnectRequest),
|
||||
Connect(ConnectRequest),
|
||||
Disconnect(DisconnectRequest),
|
||||
Ping(PingRequest),
|
||||
Health(HealthRequest),
|
||||
}
|
||||
@@ -39,35 +32,10 @@ pub struct DataRequest {
|
||||
pub ip_packets: bytes::Bytes,
|
||||
}
|
||||
|
||||
// A static connect request is when the client provides the internal IP address it will use on the
|
||||
// ip packet router.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct StaticConnectRequest {
|
||||
pub request_id: u64,
|
||||
|
||||
// The requested internal IP addresses.
|
||||
pub ips: IpPair,
|
||||
|
||||
// The maximum time in milliseconds the IPR should wait when filling up a mix packet
|
||||
// with ip packets.
|
||||
pub buffer_timeout: Option<u64>,
|
||||
|
||||
// Timestamp of when the request was sent by the client.
|
||||
pub timestamp: OffsetDateTime,
|
||||
|
||||
pub sender: SentBy,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct SignedStaticConnectRequest {
|
||||
pub request: StaticConnectRequest,
|
||||
pub signature: Option<ed25519::Signature>,
|
||||
}
|
||||
|
||||
// A dynamic connect request is when the client does not provide the internal IP address it will use
|
||||
// on the ip packet router, and instead requests one to be assigned to it.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct DynamicConnectRequest {
|
||||
pub struct ConnectRequest {
|
||||
pub request_id: u64,
|
||||
|
||||
// The maximum time in milliseconds the IPR should wait when filling up a mix packet
|
||||
@@ -76,14 +44,6 @@ pub struct DynamicConnectRequest {
|
||||
|
||||
// Timestamp of when the request was sent by the client.
|
||||
pub timestamp: OffsetDateTime,
|
||||
|
||||
pub sender: SentBy,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct SignedDynamicConnectRequest {
|
||||
pub request: DynamicConnectRequest,
|
||||
pub signature: Option<ed25519::Signature>,
|
||||
}
|
||||
|
||||
// A disconnect request is when the client wants to disconnect from the ip packet router and free
|
||||
@@ -94,14 +54,6 @@ pub struct DisconnectRequest {
|
||||
|
||||
// Timestamp of when the request was sent by the client.
|
||||
pub timestamp: OffsetDateTime,
|
||||
|
||||
pub sender: SentBy,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct SignedDisconnectRequest {
|
||||
pub request: DisconnectRequest,
|
||||
pub signature: Option<ed25519::Signature>,
|
||||
}
|
||||
|
||||
// A ping request is when the client wants to check if the ip packet router is still alive.
|
||||
@@ -109,8 +61,6 @@ pub struct SignedDisconnectRequest {
|
||||
pub struct PingRequest {
|
||||
pub request_id: u64,
|
||||
|
||||
pub sender: SentBy,
|
||||
|
||||
// Timestamp of when the request was sent by the client.
|
||||
pub timestamp: OffsetDateTime,
|
||||
}
|
||||
@@ -119,142 +69,89 @@ pub struct PingRequest {
|
||||
pub struct HealthRequest {
|
||||
pub request_id: u64,
|
||||
|
||||
pub sender: SentBy,
|
||||
|
||||
// Timestamp of when the request was sent by the client.
|
||||
pub timestamp: OffsetDateTime,
|
||||
}
|
||||
|
||||
// When constructing the request, use this return address. It has the keypair to be able to sign
|
||||
// the request if we reveal the sender.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ReturnAddress {
|
||||
AnonymousSenderTag,
|
||||
NymAddress {
|
||||
reply_to: Box<Recipient>,
|
||||
signing_keypair: Arc<ed25519::KeyPair>,
|
||||
},
|
||||
}
|
||||
|
||||
// The serialized sender field in the request, that does not contain the keypair.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub enum SentBy {
|
||||
AnonymousSenderTag,
|
||||
NymAddress(Box<Recipient>),
|
||||
}
|
||||
|
||||
impl IpPacketRequest {
|
||||
pub fn new_connect_request(
|
||||
ips: Option<IpPair>,
|
||||
buffer_timeout: Option<u64>,
|
||||
return_address: ReturnAddress,
|
||||
) -> Result<(Self, u64), SignatureError> {
|
||||
pub fn new_connect_request(buffer_timeout: Option<u64>) -> (Self, u64) {
|
||||
let protocol = Protocol {
|
||||
version: VERSION,
|
||||
service_provider_type: ServiceProviderType::IpPacketRouter,
|
||||
};
|
||||
let request_id = rand::random();
|
||||
let timestamp = OffsetDateTime::now_utc();
|
||||
let sender = return_address.clone().into();
|
||||
let request = if let Some(ips) = ips {
|
||||
let request = StaticConnectRequest {
|
||||
request_id,
|
||||
ips,
|
||||
buffer_timeout,
|
||||
timestamp,
|
||||
sender,
|
||||
};
|
||||
let signature = return_address
|
||||
.signing_key()
|
||||
.map(|keypair| {
|
||||
request
|
||||
.to_bytes()
|
||||
.map(|bytes| keypair.private_key().sign(bytes))
|
||||
})
|
||||
.transpose()?;
|
||||
ControlRequest::StaticConnect(SignedStaticConnectRequest { request, signature })
|
||||
} else {
|
||||
let request = DynamicConnectRequest {
|
||||
request_id,
|
||||
buffer_timeout,
|
||||
timestamp,
|
||||
sender,
|
||||
};
|
||||
let signature = return_address
|
||||
.signing_key()
|
||||
.map(|keypair| {
|
||||
request
|
||||
.to_bytes()
|
||||
.map(|bytes| keypair.private_key().sign(bytes))
|
||||
})
|
||||
.transpose()?;
|
||||
ControlRequest::DynamicConnect(SignedDynamicConnectRequest { request, signature })
|
||||
let connect = ConnectRequest {
|
||||
request_id,
|
||||
buffer_timeout,
|
||||
timestamp,
|
||||
};
|
||||
let request = Self {
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::Control(Box::new(request)),
|
||||
protocol,
|
||||
data: IpPacketRequestData::Control(Box::new(ControlRequest::Connect(connect))),
|
||||
};
|
||||
Ok((request, request_id))
|
||||
(request, request_id)
|
||||
}
|
||||
|
||||
pub fn new_disconnect_request(
|
||||
return_address: ReturnAddress,
|
||||
) -> Result<(Self, u64), SignatureError> {
|
||||
pub fn new_disconnect_request() -> (Self, u64) {
|
||||
let protocol = Protocol {
|
||||
version: VERSION,
|
||||
service_provider_type: ServiceProviderType::IpPacketRouter,
|
||||
};
|
||||
let request_id = rand::random();
|
||||
let timestamp = OffsetDateTime::now_utc();
|
||||
let sender = return_address.clone().into();
|
||||
let request = DisconnectRequest {
|
||||
let disconnect = DisconnectRequest {
|
||||
request_id,
|
||||
timestamp,
|
||||
sender,
|
||||
};
|
||||
let signature = return_address
|
||||
.signing_key()
|
||||
.map(|keypair| {
|
||||
request
|
||||
.to_bytes()
|
||||
.map(|bytes| keypair.private_key().sign(bytes))
|
||||
})
|
||||
.transpose()?;
|
||||
let request = Self {
|
||||
version: VERSION,
|
||||
data: IpPacketRequestData::Control(Box::new(ControlRequest::Disconnect(
|
||||
SignedDisconnectRequest { request, signature },
|
||||
))),
|
||||
protocol,
|
||||
data: IpPacketRequestData::Control(Box::new(ControlRequest::Disconnect(disconnect))),
|
||||
};
|
||||
Ok((request, request_id))
|
||||
(request, request_id)
|
||||
}
|
||||
|
||||
pub fn new_data_request(ip_packets: bytes::Bytes) -> Self {
|
||||
Self {
|
||||
version: VERSION,
|
||||
protocol: Protocol {
|
||||
version: VERSION,
|
||||
service_provider_type: ServiceProviderType::IpPacketRouter,
|
||||
},
|
||||
data: IpPacketRequestData::Data(DataRequest { ip_packets }),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_ping(return_address: ReturnAddress) -> (Self, u64) {
|
||||
pub fn new_ping() -> (Self, u64) {
|
||||
let protocol = Protocol {
|
||||
version: VERSION,
|
||||
service_provider_type: ServiceProviderType::IpPacketRouter,
|
||||
};
|
||||
let request_id = rand::random();
|
||||
let timestamp = OffsetDateTime::now_utc();
|
||||
let sender = return_address.into();
|
||||
let ping_request = PingRequest {
|
||||
request_id,
|
||||
sender,
|
||||
timestamp,
|
||||
};
|
||||
let request = Self {
|
||||
version: VERSION,
|
||||
protocol,
|
||||
data: IpPacketRequestData::Control(Box::new(ControlRequest::Ping(ping_request))),
|
||||
};
|
||||
(request, request_id)
|
||||
}
|
||||
|
||||
pub fn new_health_request(return_address: ReturnAddress) -> (Self, u64) {
|
||||
pub fn new_health_request() -> (Self, u64) {
|
||||
let protocol = Protocol {
|
||||
version: VERSION,
|
||||
service_provider_type: ServiceProviderType::IpPacketRouter,
|
||||
};
|
||||
let request_id = rand::random();
|
||||
let timestamp = OffsetDateTime::now_utc();
|
||||
let sender = return_address.into();
|
||||
let health_request = HealthRequest {
|
||||
request_id,
|
||||
sender,
|
||||
timestamp,
|
||||
};
|
||||
let request = Self {
|
||||
version: VERSION,
|
||||
protocol,
|
||||
data: IpPacketRequestData::Control(Box::new(ControlRequest::Health(health_request))),
|
||||
};
|
||||
(request, request_id)
|
||||
@@ -267,13 +164,6 @@ impl IpPacketRequest {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn verify(&self) -> Result<(), SignatureError> {
|
||||
match &self.data {
|
||||
IpPacketRequestData::Control(c) => c.verify(),
|
||||
IpPacketRequestData::Data(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
|
||||
use bincode::Options;
|
||||
crate::make_bincode_serializer().serialize(self)
|
||||
@@ -292,7 +182,7 @@ impl fmt::Display for IpPacketRequest {
|
||||
write!(
|
||||
f,
|
||||
"IpPacketRequest {{ version: {}, data: {} }}",
|
||||
self.version, self.data
|
||||
self.protocol.version, self.data
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -309,30 +199,18 @@ impl fmt::Display for IpPacketRequestData {
|
||||
impl ControlRequest {
|
||||
fn id(&self) -> u64 {
|
||||
match self {
|
||||
ControlRequest::StaticConnect(request) => request.request.request_id,
|
||||
ControlRequest::DynamicConnect(request) => request.request.request_id,
|
||||
ControlRequest::Disconnect(request) => request.request.request_id,
|
||||
ControlRequest::Connect(request) => request.request_id,
|
||||
ControlRequest::Disconnect(request) => request.request_id,
|
||||
ControlRequest::Ping(request) => request.request_id,
|
||||
ControlRequest::Health(request) => request.request_id,
|
||||
}
|
||||
}
|
||||
|
||||
fn verify(&self) -> Result<(), SignatureError> {
|
||||
match self {
|
||||
ControlRequest::StaticConnect(request) => request.verify(),
|
||||
ControlRequest::DynamicConnect(request) => request.verify(),
|
||||
ControlRequest::Disconnect(request) => request.verify(),
|
||||
ControlRequest::Ping(_) => Ok(()),
|
||||
ControlRequest::Health(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ControlRequest {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ControlRequest::StaticConnect(_) => write!(f, "StaticConnect"),
|
||||
ControlRequest::DynamicConnect(_) => write!(f, "DynamicConnect"),
|
||||
ControlRequest::Connect(_) => write!(f, "Connect"),
|
||||
ControlRequest::Disconnect(_) => write!(f, "Disconnect"),
|
||||
ControlRequest::Ping(_) => write!(f, "Ping"),
|
||||
ControlRequest::Health(_) => write!(f, "Health"),
|
||||
@@ -340,128 +218,17 @@ impl fmt::Display for ControlRequest {
|
||||
}
|
||||
}
|
||||
|
||||
impl StaticConnectRequest {
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, SignatureError> {
|
||||
impl ConnectRequest {
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
|
||||
use bincode::Options;
|
||||
crate::make_bincode_serializer()
|
||||
.serialize(self)
|
||||
.map_err(|error| SignatureError::RequestSerializationError {
|
||||
message: "failed to serialize request to binary".to_string(),
|
||||
error,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl SignedRequest for SignedStaticConnectRequest {
|
||||
fn request_as_bytes(&self) -> Result<Vec<u8>, SignatureError> {
|
||||
self.request.to_bytes()
|
||||
}
|
||||
|
||||
fn timestamp(&self) -> OffsetDateTime {
|
||||
self.request.timestamp
|
||||
}
|
||||
|
||||
fn identity(&self) -> Option<&ed25519::PublicKey> {
|
||||
self.request.sender.identity()
|
||||
}
|
||||
|
||||
fn signature(&self) -> Option<&ed25519::Signature> {
|
||||
self.signature.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl DynamicConnectRequest {
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, SignatureError> {
|
||||
use bincode::Options;
|
||||
crate::make_bincode_serializer()
|
||||
.serialize(self)
|
||||
.map_err(|error| SignatureError::RequestSerializationError {
|
||||
message: "failed to serialize request to binary".to_string(),
|
||||
error,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl SignedRequest for SignedDynamicConnectRequest {
|
||||
fn request_as_bytes(&self) -> Result<Vec<u8>, SignatureError> {
|
||||
self.request.to_bytes()
|
||||
}
|
||||
|
||||
fn timestamp(&self) -> OffsetDateTime {
|
||||
self.request.timestamp
|
||||
}
|
||||
|
||||
fn identity(&self) -> Option<&ed25519::PublicKey> {
|
||||
self.request.sender.identity()
|
||||
}
|
||||
|
||||
fn signature(&self) -> Option<&ed25519::Signature> {
|
||||
self.signature.as_ref()
|
||||
crate::make_bincode_serializer().serialize(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl DisconnectRequest {
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, SignatureError> {
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
|
||||
use bincode::Options;
|
||||
crate::make_bincode_serializer()
|
||||
.serialize(self)
|
||||
.map_err(|error| SignatureError::RequestSerializationError {
|
||||
message: "failed to serialize request to binary".to_string(),
|
||||
error,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl SignedRequest for SignedDisconnectRequest {
|
||||
fn request_as_bytes(&self) -> Result<Vec<u8>, SignatureError> {
|
||||
self.request.to_bytes()
|
||||
}
|
||||
|
||||
fn timestamp(&self) -> OffsetDateTime {
|
||||
self.request.timestamp
|
||||
}
|
||||
|
||||
fn identity(&self) -> Option<&ed25519::PublicKey> {
|
||||
self.request.sender.identity()
|
||||
}
|
||||
|
||||
fn signature(&self) -> Option<&ed25519::Signature> {
|
||||
self.signature.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl SentBy {
|
||||
fn identity(&self) -> Option<&ed25519::PublicKey> {
|
||||
match self {
|
||||
SentBy::AnonymousSenderTag => None,
|
||||
SentBy::NymAddress(recipient) => Some(recipient.identity()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Recipient> for SentBy {
|
||||
fn from(recipient: Recipient) -> Self {
|
||||
SentBy::NymAddress(Box::new(recipient))
|
||||
}
|
||||
}
|
||||
|
||||
impl ReturnAddress {
|
||||
fn signing_key(&self) -> Option<&ed25519::KeyPair> {
|
||||
match self {
|
||||
ReturnAddress::AnonymousSenderTag => None,
|
||||
ReturnAddress::NymAddress {
|
||||
signing_keypair, ..
|
||||
} => Some(signing_keypair.as_ref()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ReturnAddress> for SentBy {
|
||||
fn from(return_address: ReturnAddress) -> Self {
|
||||
match return_address {
|
||||
ReturnAddress::AnonymousSenderTag => SentBy::AnonymousSenderTag,
|
||||
ReturnAddress::NymAddress { reply_to, .. } => SentBy::NymAddress(reply_to),
|
||||
}
|
||||
crate::make_bincode_serializer().serialize(self)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,47 +237,44 @@ mod tests {
|
||||
use time::macros::datetime;
|
||||
|
||||
use super::*;
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn check_size_of_request() {
|
||||
let connect = IpPacketRequest {
|
||||
version: 4,
|
||||
data: IpPacketRequestData::Control(Box::new(ControlRequest::StaticConnect(
|
||||
SignedStaticConnectRequest {
|
||||
request: StaticConnectRequest {
|
||||
request_id: 123,
|
||||
ips: IpPair::new(
|
||||
Ipv4Addr::from_str("10.0.0.1").unwrap(),
|
||||
Ipv6Addr::from_str("fc00::1").unwrap(),
|
||||
),
|
||||
buffer_timeout: None,
|
||||
timestamp: datetime!(2024-01-01 12:59:59.5 UTC),
|
||||
sender: SentBy::AnonymousSenderTag,
|
||||
},
|
||||
signature: None,
|
||||
},
|
||||
))),
|
||||
protocol: Protocol {
|
||||
version: 4,
|
||||
service_provider_type: ServiceProviderType::IpPacketRouter,
|
||||
},
|
||||
data: IpPacketRequestData::Control(Box::new(ControlRequest::Connect(ConnectRequest {
|
||||
request_id: 123,
|
||||
buffer_timeout: None,
|
||||
timestamp: datetime!(2024-01-01 12:59:59.5 UTC),
|
||||
}))),
|
||||
};
|
||||
assert_eq!(connect.to_bytes().unwrap().len(), 42);
|
||||
assert_eq!(connect.to_bytes().unwrap().len(), 21);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_size_of_data() {
|
||||
let data = IpPacketRequest {
|
||||
version: 4,
|
||||
protocol: Protocol {
|
||||
version: 4,
|
||||
service_provider_type: ServiceProviderType::IpPacketRouter,
|
||||
},
|
||||
data: IpPacketRequestData::Data(DataRequest {
|
||||
ip_packets: bytes::Bytes::from(vec![1u8; 32]),
|
||||
}),
|
||||
};
|
||||
assert_eq!(data.to_bytes().unwrap().len(), 35);
|
||||
assert_eq!(data.to_bytes().unwrap().len(), 36);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_and_deserialize_data_request() {
|
||||
let data = IpPacketRequest {
|
||||
version: 4,
|
||||
protocol: Protocol {
|
||||
version: 4,
|
||||
service_provider_type: ServiceProviderType::IpPacketRouter,
|
||||
},
|
||||
data: IpPacketRequestData::Data(DataRequest {
|
||||
ip_packets: bytes::Bytes::from(vec![1, 2, 4, 2, 5]),
|
||||
}),
|
||||
@@ -525,7 +289,11 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(deserialized.version, 4);
|
||||
assert_eq!(deserialized.protocol.version, 4);
|
||||
assert_eq!(
|
||||
deserialized.protocol.service_provider_type,
|
||||
ServiceProviderType::IpPacketRouter
|
||||
);
|
||||
assert_eq!(
|
||||
deserialized.data,
|
||||
IpPacketRequestData::Data(DataRequest {
|
||||
|
||||
@@ -24,11 +24,8 @@ pub struct DataResponse {
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum ControlResponse {
|
||||
// Response for a static connect request
|
||||
StaticConnect(StaticConnectResponse),
|
||||
|
||||
// Response for a dynamic connect request
|
||||
DynamicConnect(DynamicConnectResponse),
|
||||
// Response for a connect request
|
||||
Connect(ConnectResponse),
|
||||
|
||||
// Response for a disconnect initiqated by the client
|
||||
Disconnect(DisconnectResponse),
|
||||
@@ -47,51 +44,24 @@ pub enum ControlResponse {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct StaticConnectResponse {
|
||||
pub struct ConnectResponse {
|
||||
pub request_id: u64,
|
||||
pub reply: StaticConnectResponseReply,
|
||||
pub reply: ConnectResponseReply,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum StaticConnectResponseReply {
|
||||
Success,
|
||||
Failure(StaticConnectFailureReason),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
|
||||
pub enum StaticConnectFailureReason {
|
||||
#[error("requested ip address is already in use")]
|
||||
RequestedIpAlreadyInUse,
|
||||
|
||||
#[error("client is already connected")]
|
||||
ClientAlreadyConnected,
|
||||
|
||||
#[error("request timestamp is out of date")]
|
||||
OutOfDateTimestamp,
|
||||
|
||||
#[error("{0}")]
|
||||
Other(String),
|
||||
pub enum ConnectResponseReply {
|
||||
Success(ConnectSuccess),
|
||||
Failure(ConnectFailureReason),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct DynamicConnectResponse {
|
||||
pub request_id: u64,
|
||||
pub reply: DynamicConnectResponseReply,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum DynamicConnectResponseReply {
|
||||
Success(DynamicConnectSuccess),
|
||||
Failure(DynamicConnectFailureReason),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct DynamicConnectSuccess {
|
||||
pub struct ConnectSuccess {
|
||||
pub ips: IpPair,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
|
||||
pub enum DynamicConnectFailureReason {
|
||||
pub enum ConnectFailureReason {
|
||||
#[error("client is already connected")]
|
||||
ClientAlreadyConnected,
|
||||
|
||||
@@ -229,8 +199,7 @@ impl IpPacketResponseData {
|
||||
impl ControlResponse {
|
||||
fn id(&self) -> Option<u64> {
|
||||
match self {
|
||||
ControlResponse::StaticConnect(response) => Some(response.request_id),
|
||||
ControlResponse::DynamicConnect(response) => Some(response.request_id),
|
||||
ControlResponse::Connect(response) => Some(response.request_id),
|
||||
ControlResponse::Disconnect(response) => Some(response.request_id),
|
||||
ControlResponse::UnrequestedDisconnect(_) => None,
|
||||
ControlResponse::Pong(response) => Some(response.request_id),
|
||||
@@ -240,20 +209,11 @@ impl ControlResponse {
|
||||
}
|
||||
}
|
||||
|
||||
impl StaticConnectResponseReply {
|
||||
impl ConnectResponseReply {
|
||||
pub fn is_success(&self) -> bool {
|
||||
match self {
|
||||
StaticConnectResponseReply::Success => true,
|
||||
StaticConnectResponseReply::Failure(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DynamicConnectResponseReply {
|
||||
pub fn is_success(&self) -> bool {
|
||||
match self {
|
||||
DynamicConnectResponseReply::Success(_) => true,
|
||||
DynamicConnectResponseReply::Failure(_) => false,
|
||||
ConnectResponseReply::Success(_) => true,
|
||||
ConnectResponseReply::Failure(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,3 +12,7 @@ readme.workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
thiserror.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
bincode.workspace = true
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum ProtocolError {
|
||||
#[error("invalid service provider type: {0}")]
|
||||
InvalidServiceProviderType(u8),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum ServiceProviderType {
|
||||
@@ -11,8 +19,103 @@ pub enum ServiceProviderType {
|
||||
Authenticator = 2,
|
||||
}
|
||||
|
||||
impl fmt::Display for ServiceProviderType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::NetworkRequester => write!(f, "NetworkRequester"),
|
||||
Self::IpPacketRouter => write!(f, "IpPacketRouter"),
|
||||
Self::Authenticator => write!(f, "Authenticator"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for ServiceProviderType {
|
||||
type Error = ProtocolError;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0 => Ok(Self::NetworkRequester),
|
||||
1 => Ok(Self::IpPacketRouter),
|
||||
2 => Ok(Self::Authenticator),
|
||||
_ => Err(ProtocolError::InvalidServiceProviderType(value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct Protocol {
|
||||
pub version: u8,
|
||||
pub service_provider_type: ServiceProviderType,
|
||||
}
|
||||
|
||||
impl TryFrom<&[u8; 2]> for Protocol {
|
||||
type Error = ProtocolError;
|
||||
|
||||
fn try_from(bytes: &[u8; 2]) -> Result<Self, Self::Error> {
|
||||
let version = bytes[0];
|
||||
let service_provider_type = ServiceProviderType::try_from(bytes[1])
|
||||
.map_err(|_| ProtocolError::InvalidServiceProviderType(bytes[1]))?;
|
||||
|
||||
Ok(Self {
|
||||
version,
|
||||
service_provider_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use bincode::Options;
|
||||
|
||||
fn make_bincode_serializer() -> impl bincode::Options {
|
||||
bincode::DefaultOptions::new()
|
||||
.with_big_endian()
|
||||
.with_varint_encoding()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn protocol_serialization() {
|
||||
let protocol = Protocol {
|
||||
version: 4,
|
||||
service_provider_type: ServiceProviderType::NetworkRequester,
|
||||
};
|
||||
|
||||
let serialized = make_bincode_serializer().serialize(&protocol).unwrap();
|
||||
let deserialized: Protocol = make_bincode_serializer().deserialize(&serialized).unwrap();
|
||||
|
||||
assert_eq!(protocol, deserialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compact_serialization() {
|
||||
let protocol = Protocol {
|
||||
version: 4,
|
||||
service_provider_type: ServiceProviderType::NetworkRequester,
|
||||
};
|
||||
|
||||
let serialized = make_bincode_serializer().serialize(&protocol).unwrap();
|
||||
assert_eq!(serialized.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn protocol_deserialization() {
|
||||
let bytes = [4, ServiceProviderType::NetworkRequester as u8];
|
||||
let deserialized = Protocol::try_from(&bytes).unwrap();
|
||||
|
||||
let expected = Protocol {
|
||||
version: 4,
|
||||
service_provider_type: ServiceProviderType::NetworkRequester,
|
||||
};
|
||||
|
||||
assert_eq!(expected, deserialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_protocol_deserialization() {
|
||||
let bytes = [4, 3];
|
||||
let deserialized = Protocol::try_from(&bytes);
|
||||
|
||||
assert!(deserialized.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ nym-ip-packet-requests = { path = "../../common/ip-packet-requests" }
|
||||
nym-network-defaults = { path = "../../common/network-defaults" }
|
||||
nym-network-requester = { path = "../network-requester" }
|
||||
nym-sdk = { path = "../../sdk/rust/nym-sdk" }
|
||||
nym-service-provider-requests-common = { path = "../../common/service-provider-requests-common" }
|
||||
nym-service-providers-common = { path = "../common" }
|
||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
||||
nym-task = { path = "../../common/task" }
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use nym_ip_packet_requests::v8::request::SentBy;
|
||||
use nym_sdk::mixnet::{AnonymousSenderTag, Recipient};
|
||||
|
||||
use crate::error::{IpPacketRouterError, Result};
|
||||
@@ -43,16 +42,3 @@ impl From<AnonymousSenderTag> for ConnectedClientId {
|
||||
ConnectedClientId::AnonymousSenderTag(tag)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(SentBy, Option<AnonymousSenderTag>)> for ConnectedClientId {
|
||||
type Error = IpPacketRouterError;
|
||||
|
||||
fn try_from((sent_by, sender_tag): (SentBy, Option<AnonymousSenderTag>)) -> Result<Self> {
|
||||
match sent_by {
|
||||
SentBy::NymAddress(nym_address) => Ok(ConnectedClientId::NymAddress(nym_address)),
|
||||
SentBy::AnonymousSenderTag => sender_tag
|
||||
.map(ConnectedClientId::AnonymousSenderTag)
|
||||
.ok_or(IpPacketRouterError::InvalidReplyTo),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ pub use nym_client_core::error::ClientCoreError;
|
||||
use nym_exit_policy::PolicyError;
|
||||
use nym_id::NymIdError;
|
||||
use nym_ip_packet_requests::sign::SignatureError;
|
||||
use nym_service_provider_requests_common::{ProtocolError, ServiceProviderType};
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum IpPacketRouterError {
|
||||
@@ -96,11 +97,20 @@ pub enum IpPacketRouterError {
|
||||
#[error("failed to verify request: {source}")]
|
||||
FailedToVerifyRequest { source: SignatureError },
|
||||
|
||||
#[error("client is connected with an invalid version: {version}")]
|
||||
InvalidConnectedClientVersion { version: u8 },
|
||||
|
||||
#[error("invalid reply-to address in the response")]
|
||||
InvalidReplyTo,
|
||||
|
||||
#[error("missing sender tag in the request")]
|
||||
MissingSenderTag,
|
||||
|
||||
#[error("unsupported response: {0}")]
|
||||
UnsupportedResponse(String),
|
||||
|
||||
#[error("invalid service provider type: {0}")]
|
||||
InvalidServiceProviderType(ServiceProviderType),
|
||||
|
||||
#[error("failed to deserialize protocol: {source}")]
|
||||
FailedToDeserializeProtocol { source: ProtocolError },
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, IpPacketRouterError>;
|
||||
|
||||
@@ -11,6 +11,7 @@ use nym_ip_packet_requests::{
|
||||
v8::request::IpPacketRequest as IpPacketRequestV8, IpPair,
|
||||
};
|
||||
use nym_sdk::mixnet::ReconstructedMessage;
|
||||
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||
use std::fmt;
|
||||
|
||||
use crate::{clients::ConnectedClientId, error::IpPacketRouterError};
|
||||
@@ -83,9 +84,23 @@ impl TryFrom<&ReconstructedMessage> for IpPacketRequest {
|
||||
fn try_from(reconstructed: &ReconstructedMessage) -> Result<Self, Self::Error> {
|
||||
let request_version = *reconstructed
|
||||
.message
|
||||
.first()
|
||||
.first_chunk::<2>()
|
||||
.ok_or(IpPacketRouterError::EmptyPacket)?;
|
||||
|
||||
// With version v8 and onwards, the type of the service provider is included in the
|
||||
// header.
|
||||
if request_version[0] >= 8 {
|
||||
let protocol = Protocol::try_from(&request_version)
|
||||
.map_err(|source| IpPacketRouterError::FailedToDeserializeProtocol { source })?;
|
||||
|
||||
if protocol.service_provider_type != ServiceProviderType::IpPacketRouter {
|
||||
return Err(IpPacketRouterError::InvalidServiceProviderType(
|
||||
protocol.service_provider_type,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let request_version = request_version[0];
|
||||
match request_version {
|
||||
6 => {
|
||||
let request_v6 = IpPacketRequestV6::from_reconstructed_message(reconstructed)
|
||||
@@ -109,10 +124,10 @@ impl TryFrom<&ReconstructedMessage> for IpPacketRequest {
|
||||
.map_err(
|
||||
|source| IpPacketRouterError::FailedToDeserializeTaggedPacket { source },
|
||||
)?;
|
||||
request_v8
|
||||
.verify()
|
||||
.map_err(|source| IpPacketRouterError::FailedToVerifyRequest { source })?;
|
||||
IpPacketRequest::try_from((request_v8, reconstructed.sender_tag))
|
||||
let sender_tag = reconstructed
|
||||
.sender_tag
|
||||
.ok_or(IpPacketRouterError::MissingSenderTag)?;
|
||||
Ok(IpPacketRequest::from((request_v8, sender_tag)))
|
||||
}
|
||||
_ => {
|
||||
log::info!("Received packet with invalid version: v{request_version}");
|
||||
|
||||
@@ -2,34 +2,27 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use nym_ip_packet_requests::v8::request::{
|
||||
ControlRequest as ControlRequestV8, DataRequest as DataRequestV8,
|
||||
DisconnectRequest as DisconnectRequestV8, DynamicConnectRequest as DynamicConnectRequestV8,
|
||||
ConnectRequest as ConnectRequestV8, ControlRequest as ControlRequestV8,
|
||||
DataRequest as DataRequestV8, DisconnectRequest as DisconnectRequestV8,
|
||||
HealthRequest as HealthRequestV8, IpPacketRequest as IpPacketRequestV8,
|
||||
IpPacketRequestData as IpPacketRequestDataV8, PingRequest as PingRequestV8,
|
||||
StaticConnectRequest as StaticConnectRequestV8,
|
||||
};
|
||||
use nym_sdk::mixnet::AnonymousSenderTag;
|
||||
|
||||
use crate::error::IpPacketRouterError;
|
||||
|
||||
use super::{
|
||||
ClientVersion, ConnectedClientId, ControlRequest, DataRequest, DisconnectRequest,
|
||||
DynamicConnectRequest, HealthRequest, IpPacketRequest, PingRequest, StaticConnectRequest,
|
||||
ClientVersion, ControlRequest, DataRequest, DisconnectRequest, DynamicConnectRequest,
|
||||
HealthRequest, IpPacketRequest, PingRequest,
|
||||
};
|
||||
|
||||
impl TryFrom<(IpPacketRequestV8, Option<AnonymousSenderTag>)> for IpPacketRequest {
|
||||
type Error = IpPacketRouterError;
|
||||
|
||||
fn try_from(
|
||||
(request, sender_tag): (IpPacketRequestV8, Option<AnonymousSenderTag>),
|
||||
) -> Result<Self, Self::Error> {
|
||||
impl From<(IpPacketRequestV8, AnonymousSenderTag)> for IpPacketRequest {
|
||||
fn from((request, sender_tag): (IpPacketRequestV8, AnonymousSenderTag)) -> Self {
|
||||
let version = ClientVersion::V8;
|
||||
Ok(match request.data {
|
||||
match request.data {
|
||||
IpPacketRequestDataV8::Data(inner) => Self::Data((inner, version).into()),
|
||||
IpPacketRequestDataV8::Control(inner) => {
|
||||
Self::Control((*inner, sender_tag, version).try_into()?)
|
||||
Self::Control((*inner, sender_tag, version).into())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,139 +35,72 @@ impl From<(DataRequestV8, ClientVersion)> for DataRequest {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(ControlRequestV8, Option<AnonymousSenderTag>, ClientVersion)> for ControlRequest {
|
||||
type Error = IpPacketRouterError;
|
||||
|
||||
fn try_from(
|
||||
(request, sender_tag, version): (
|
||||
ControlRequestV8,
|
||||
Option<AnonymousSenderTag>,
|
||||
ClientVersion,
|
||||
),
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(match request {
|
||||
ControlRequestV8::StaticConnect(inner) => {
|
||||
ControlRequest::StaticConnect((inner.request, sender_tag, version).try_into()?)
|
||||
}
|
||||
ControlRequestV8::DynamicConnect(inner) => {
|
||||
ControlRequest::DynamicConnect((inner.request, sender_tag, version).try_into()?)
|
||||
impl From<(ControlRequestV8, AnonymousSenderTag, ClientVersion)> for ControlRequest {
|
||||
fn from(
|
||||
(request, sender_tag, version): (ControlRequestV8, AnonymousSenderTag, ClientVersion),
|
||||
) -> Self {
|
||||
match request {
|
||||
ControlRequestV8::Connect(inner) => {
|
||||
ControlRequest::DynamicConnect((inner, sender_tag, version).into())
|
||||
}
|
||||
ControlRequestV8::Disconnect(inner) => {
|
||||
ControlRequest::Disconnect((inner.request, sender_tag, version).try_into()?)
|
||||
ControlRequest::Disconnect((inner, sender_tag, version).into())
|
||||
}
|
||||
ControlRequestV8::Ping(inner) => {
|
||||
ControlRequest::Ping((inner, sender_tag, version).try_into()?)
|
||||
ControlRequest::Ping((inner, sender_tag, version).into())
|
||||
}
|
||||
ControlRequestV8::Health(inner) => {
|
||||
ControlRequest::Health((inner, sender_tag, version).try_into()?)
|
||||
ControlRequest::Health((inner, sender_tag, version).into())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
TryFrom<(
|
||||
StaticConnectRequestV8,
|
||||
Option<AnonymousSenderTag>,
|
||||
ClientVersion,
|
||||
)> for StaticConnectRequest
|
||||
{
|
||||
type Error = IpPacketRouterError;
|
||||
|
||||
fn try_from(
|
||||
(request, sender_tag, version): (
|
||||
StaticConnectRequestV8,
|
||||
Option<AnonymousSenderTag>,
|
||||
ClientVersion,
|
||||
),
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
impl From<(ConnectRequestV8, AnonymousSenderTag, ClientVersion)> for DynamicConnectRequest {
|
||||
fn from(
|
||||
(request, sender_tag, version): (ConnectRequestV8, AnonymousSenderTag, ClientVersion),
|
||||
) -> Self {
|
||||
Self {
|
||||
version,
|
||||
request_id: request.request_id,
|
||||
sent_by: ConnectedClientId::try_from((request.sender, sender_tag))?,
|
||||
ips: request.ips,
|
||||
sent_by: sender_tag.into(),
|
||||
buffer_timeout: request.buffer_timeout,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
TryFrom<(
|
||||
DynamicConnectRequestV8,
|
||||
Option<AnonymousSenderTag>,
|
||||
ClientVersion,
|
||||
)> for DynamicConnectRequest
|
||||
{
|
||||
type Error = IpPacketRouterError;
|
||||
|
||||
fn try_from(
|
||||
(request, sender_tag, version): (
|
||||
DynamicConnectRequestV8,
|
||||
Option<AnonymousSenderTag>,
|
||||
ClientVersion,
|
||||
),
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
impl From<(DisconnectRequestV8, AnonymousSenderTag, ClientVersion)> for DisconnectRequest {
|
||||
fn from(
|
||||
(request, sender_tag, version): (DisconnectRequestV8, AnonymousSenderTag, ClientVersion),
|
||||
) -> Self {
|
||||
Self {
|
||||
version,
|
||||
request_id: request.request_id,
|
||||
sent_by: ConnectedClientId::try_from((request.sender, sender_tag))?,
|
||||
buffer_timeout: request.buffer_timeout,
|
||||
})
|
||||
sent_by: sender_tag.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
TryFrom<(
|
||||
DisconnectRequestV8,
|
||||
Option<AnonymousSenderTag>,
|
||||
ClientVersion,
|
||||
)> for DisconnectRequest
|
||||
{
|
||||
type Error = IpPacketRouterError;
|
||||
|
||||
fn try_from(
|
||||
(request, sender_tag, version): (
|
||||
DisconnectRequestV8,
|
||||
Option<AnonymousSenderTag>,
|
||||
ClientVersion,
|
||||
),
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
impl From<(PingRequestV8, AnonymousSenderTag, ClientVersion)> for PingRequest {
|
||||
fn from(
|
||||
(request, sender_tag, version): (PingRequestV8, AnonymousSenderTag, ClientVersion),
|
||||
) -> Self {
|
||||
Self {
|
||||
version,
|
||||
request_id: request.request_id,
|
||||
sent_by: ConnectedClientId::try_from((request.sender, sender_tag))?,
|
||||
})
|
||||
sent_by: sender_tag.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(PingRequestV8, Option<AnonymousSenderTag>, ClientVersion)> for PingRequest {
|
||||
type Error = IpPacketRouterError;
|
||||
|
||||
fn try_from(
|
||||
(request, sender_tag, version): (PingRequestV8, Option<AnonymousSenderTag>, ClientVersion),
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
impl From<(HealthRequestV8, AnonymousSenderTag, ClientVersion)> for HealthRequest {
|
||||
fn from(
|
||||
(request, sender_tag, version): (HealthRequestV8, AnonymousSenderTag, ClientVersion),
|
||||
) -> Self {
|
||||
Self {
|
||||
version,
|
||||
request_id: request.request_id,
|
||||
sent_by: ConnectedClientId::try_from((request.sender, sender_tag))?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(HealthRequestV8, Option<AnonymousSenderTag>, ClientVersion)> for HealthRequest {
|
||||
type Error = IpPacketRouterError;
|
||||
|
||||
fn try_from(
|
||||
(request, sender_tag, version): (
|
||||
HealthRequestV8,
|
||||
Option<AnonymousSenderTag>,
|
||||
ClientVersion,
|
||||
),
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
version,
|
||||
request_id: request.request_id,
|
||||
sent_by: ConnectedClientId::try_from((request.sender, sender_tag))?,
|
||||
})
|
||||
sent_by: sender_tag.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ impl VersionedResponse {
|
||||
match self.version {
|
||||
ClientVersion::V6 => IpPacketResponseV6::try_from(self)?.to_bytes(),
|
||||
ClientVersion::V7 => IpPacketResponseV7::try_from(self)?.to_bytes(),
|
||||
ClientVersion::V8 => IpPacketResponseV8::from(self).to_bytes(),
|
||||
ClientVersion::V8 => IpPacketResponseV8::try_from(self)?.to_bytes(),
|
||||
}
|
||||
.map_err(|err| IpPacketRouterError::FailedToSerializeResponsePacket { source: err })
|
||||
}
|
||||
|
||||
@@ -2,46 +2,44 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use nym_ip_packet_requests::v8::response::{
|
||||
ConnectFailureReason as ConnectFailureReasonV8, ConnectResponse as ConnectResponseV8,
|
||||
ConnectResponseReply as ConnectResponseReplyV8, ConnectSuccess as ConnectSuccessV8,
|
||||
ControlResponse as ControlResponseV8, DisconnectFailureReason as DisconnectFailureReasonV8,
|
||||
DisconnectResponse as DisconnectResponseV8,
|
||||
DisconnectResponseReply as DisconnectResponseReplyV8,
|
||||
DynamicConnectFailureReason as DynamicConnectFailureReasonV8,
|
||||
DynamicConnectResponse as DynamicConnectResponseV8,
|
||||
DynamicConnectResponseReply as DynamicConnectResponseReplyV8,
|
||||
DynamicConnectSuccess as DynamicConnectSuccessV8, HealthResponse as HealthResponseV8,
|
||||
DisconnectResponseReply as DisconnectResponseReplyV8, HealthResponse as HealthResponseV8,
|
||||
HealthResponseReply as HealthResponseReplyV8, InfoLevel as InfoLevelV8,
|
||||
InfoResponse as InfoResponseV8, InfoResponseReply as InfoResponseReplyV8,
|
||||
IpPacketResponse as IpPacketResponseV8, IpPacketResponseData as IpPacketResponseDataV8,
|
||||
PongResponse as PongResponseV8, StaticConnectFailureReason as StaticConnectFailureReasonV8,
|
||||
StaticConnectResponse as StaticConnectResponseV8,
|
||||
StaticConnectResponseReply as StaticConnectResponseReplyV8,
|
||||
PongResponse as PongResponseV8,
|
||||
};
|
||||
|
||||
use crate::error::IpPacketRouterError;
|
||||
|
||||
use super::{
|
||||
DisconnectFailureReason, DisconnectResponse, DynamicConnectFailureReason,
|
||||
DynamicConnectResponse, DynamicConnectSuccess, HealthResponse, InfoLevel, InfoResponseReply,
|
||||
Response, StaticConnectFailureReason, StaticConnectResponse, VersionedResponse,
|
||||
Response, VersionedResponse,
|
||||
};
|
||||
|
||||
impl From<VersionedResponse> for IpPacketResponseV8 {
|
||||
fn from(response: VersionedResponse) -> Self {
|
||||
impl TryFrom<VersionedResponse> for IpPacketResponseV8 {
|
||||
type Error = IpPacketRouterError;
|
||||
|
||||
fn try_from(response: VersionedResponse) -> Result<Self, Self::Error> {
|
||||
let version = response.version.into_u8();
|
||||
let data =
|
||||
match response.response {
|
||||
Response::StaticConnect { request_id, reply } => IpPacketResponseDataV8::Control(
|
||||
Box::new(ControlResponseV8::StaticConnect(StaticConnectResponseV8 {
|
||||
Response::StaticConnect { .. } => {
|
||||
return Err(IpPacketRouterError::UnsupportedResponse(format!(
|
||||
"Static connect response is not supported in version {}",
|
||||
version
|
||||
)))
|
||||
}
|
||||
Response::DynamicConnect { request_id, reply } => IpPacketResponseDataV8::Control(
|
||||
Box::new(ControlResponseV8::Connect(ConnectResponseV8 {
|
||||
request_id,
|
||||
reply: reply.into(),
|
||||
})),
|
||||
),
|
||||
Response::DynamicConnect { request_id, reply } => {
|
||||
IpPacketResponseDataV8::Control(Box::new(ControlResponseV8::DynamicConnect(
|
||||
DynamicConnectResponseV8 {
|
||||
request_id,
|
||||
reply: reply.into(),
|
||||
},
|
||||
)))
|
||||
}
|
||||
Response::Disconnect { request_id, reply } => IpPacketResponseDataV8::Control(
|
||||
Box::new(ControlResponseV8::Disconnect(DisconnectResponseV8 {
|
||||
request_id,
|
||||
@@ -66,61 +64,29 @@ impl From<VersionedResponse> for IpPacketResponseV8 {
|
||||
)),
|
||||
};
|
||||
|
||||
IpPacketResponseV8 { version, data }
|
||||
Ok(IpPacketResponseV8 { version, data })
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StaticConnectResponse> for StaticConnectResponseReplyV8 {
|
||||
fn from(reply: StaticConnectResponse) -> Self {
|
||||
match reply {
|
||||
StaticConnectResponse::Success => StaticConnectResponseReplyV8::Success,
|
||||
StaticConnectResponse::Failure(err) => {
|
||||
StaticConnectResponseReplyV8::Failure(err.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StaticConnectFailureReason> for StaticConnectFailureReasonV8 {
|
||||
fn from(reason: StaticConnectFailureReason) -> Self {
|
||||
match reason {
|
||||
StaticConnectFailureReason::RequestedIpAlreadyInUse => {
|
||||
StaticConnectFailureReasonV8::RequestedIpAlreadyInUse
|
||||
}
|
||||
StaticConnectFailureReason::ClientAlreadyConnected => {
|
||||
StaticConnectFailureReasonV8::ClientAlreadyConnected
|
||||
}
|
||||
StaticConnectFailureReason::OutOfDateTimestamp => {
|
||||
StaticConnectFailureReasonV8::OutOfDateTimestamp
|
||||
}
|
||||
StaticConnectFailureReason::Other(err) => StaticConnectFailureReasonV8::Other(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DynamicConnectResponse> for DynamicConnectResponseReplyV8 {
|
||||
impl From<DynamicConnectResponse> for ConnectResponseReplyV8 {
|
||||
fn from(reply: DynamicConnectResponse) -> Self {
|
||||
match reply {
|
||||
DynamicConnectResponse::Success(DynamicConnectSuccess { ips }) => {
|
||||
DynamicConnectResponseReplyV8::Success(DynamicConnectSuccessV8 { ips })
|
||||
}
|
||||
DynamicConnectResponse::Failure(err) => {
|
||||
DynamicConnectResponseReplyV8::Failure(err.into())
|
||||
ConnectResponseReplyV8::Success(ConnectSuccessV8 { ips })
|
||||
}
|
||||
DynamicConnectResponse::Failure(err) => ConnectResponseReplyV8::Failure(err.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DynamicConnectFailureReason> for DynamicConnectFailureReasonV8 {
|
||||
impl From<DynamicConnectFailureReason> for ConnectFailureReasonV8 {
|
||||
fn from(reason: DynamicConnectFailureReason) -> Self {
|
||||
match reason {
|
||||
DynamicConnectFailureReason::ClientAlreadyConnected => {
|
||||
DynamicConnectFailureReasonV8::ClientAlreadyConnected
|
||||
ConnectFailureReasonV8::ClientAlreadyConnected
|
||||
}
|
||||
DynamicConnectFailureReason::NoAvailableIp => {
|
||||
DynamicConnectFailureReasonV8::NoAvailableIp
|
||||
}
|
||||
DynamicConnectFailureReason::Other(err) => DynamicConnectFailureReasonV8::Other(err),
|
||||
DynamicConnectFailureReason::NoAvailableIp => ConnectFailureReasonV8::NoAvailableIp,
|
||||
DynamicConnectFailureReason::Other(err) => ConnectFailureReasonV8::Other(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user