Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8941c47f7d | |||
| dd31af50ff | |||
| ef5970c2f0 | |||
| 62146b1188 | |||
| 1c8178a966 | |||
| 1ddbb970d0 | |||
| 3f500af7a7 | |||
| e2c5b10c6b | |||
| 737cd628ff | |||
| 96dbe583ce | |||
| 0f8598ad52 | |||
| 9c271d7344 | |||
| 6339039500 | |||
| 898c9dd11f | |||
| ace3aff900 | |||
| 4d4e786d5e | |||
| 2b88c717c7 | |||
| 71b4e650d3 | |||
| f9727ce0a0 | |||
| c93b056e36 | |||
| 4fc5139e29 | |||
| 795c73f75c | |||
| 7dd0f6cfa1 | |||
| 7042d155eb | |||
| c10d97372f | |||
| f2be036009 | |||
| 5e6bd80d45 | |||
| ef5d503692 | |||
| 901557ad04 | |||
| f6a796fe71 | |||
| 7c23cd2183 | |||
| 211f90692a | |||
| 9b44095b62 | |||
| f347a4f349 | |||
| 595d034f64 | |||
| 872ae85136 | |||
| 25ef5f52b4 | |||
| 54d193caa9 | |||
| 4f106c3d98 | |||
| ed9883fc16 | |||
| 6f0c447f88 | |||
| bf88c0c9d4 | |||
| 27b5bde7cf | |||
| 3da3c8396f | |||
| 88f383dd29 | |||
| d56ca5fa78 | |||
| 63582dd4e1 | |||
| 39ee22e501 | |||
| 26056909b7 | |||
| 4fcb8ed202 | |||
| 5536d49f65 | |||
| 5621c94c0a | |||
| 0011975ae8 | |||
| 8460270f62 | |||
| d313e4ef05 | |||
| ad389c4fba | |||
| 9d021481d0 | |||
| afe4c7fb03 | |||
| 583edbc2ef |
Generated
+9
-9
@@ -5346,7 +5346,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-api"
|
||||
version = "1.1.75"
|
||||
version = "1.1.74"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -5591,7 +5591,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-cli"
|
||||
version = "1.1.72"
|
||||
version = "1.1.71"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.22.1",
|
||||
@@ -5674,7 +5674,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client"
|
||||
version = "1.1.72"
|
||||
version = "1.1.71"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"clap",
|
||||
@@ -7076,7 +7076,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.73"
|
||||
version = "1.1.72"
|
||||
dependencies = [
|
||||
"addr",
|
||||
"anyhow",
|
||||
@@ -7126,7 +7126,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node"
|
||||
version = "1.27.0"
|
||||
version = "1.26.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
@@ -7263,7 +7263,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node-status-agent"
|
||||
version = "1.1.2-test"
|
||||
version = "1.1.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@@ -7282,7 +7282,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node-status-api"
|
||||
version = "4.1.0-test"
|
||||
version = "4.1.0"
|
||||
dependencies = [
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
@@ -7672,7 +7672,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.72"
|
||||
version = "1.1.71"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"clap",
|
||||
@@ -8469,7 +8469,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nymvisor"
|
||||
version = "0.1.37"
|
||||
version = "0.1.36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-client"
|
||||
version = "1.1.72"
|
||||
version = "1.1.71"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.72"
|
||||
version = "1.1.71"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||
edition = "2021"
|
||||
|
||||
@@ -48,7 +48,7 @@ pub(crate) fn encrypt_lp_packet(
|
||||
) -> Result<EncryptedLpPacket, LpError> {
|
||||
let mut plaintext = BytesMut::with_capacity(InnerHeader::SIZE + packet.message().len());
|
||||
packet.header().inner.encode(&mut plaintext);
|
||||
packet.message().encode(&mut plaintext);
|
||||
packet.message().encode_content(&mut plaintext);
|
||||
|
||||
let ciphertext = encrypt_data(plaintext.as_ref(), transport)?;
|
||||
|
||||
@@ -67,7 +67,7 @@ pub(crate) fn decrypt_lp_packet(
|
||||
|
||||
let inner_header = InnerHeader::parse(&plaintext)?;
|
||||
let payload = &plaintext[InnerHeader::SIZE..];
|
||||
let message = LpMessage::decode(payload)?;
|
||||
let message = LpMessage::decode_content(payload, inner_header.message_type)?;
|
||||
|
||||
Ok(LpPacket::new(
|
||||
LpHeader {
|
||||
@@ -82,7 +82,7 @@ pub(crate) fn decrypt_lp_packet(
|
||||
mod tests {
|
||||
use crate::LpError;
|
||||
use crate::codec::{decrypt_data, decrypt_lp_packet, encrypt_data, encrypt_lp_packet};
|
||||
use crate::packet::{EncryptedLpPacket, LpHeader, LpMessage, LpPacket};
|
||||
use crate::packet::{EncryptedLpPacket, LpHeader, LpMessage, LpPacket, MessageType};
|
||||
use crate::peer::mock_peers;
|
||||
use crate::psq::initiator::{build_psq_ciphersuite, build_psq_principal};
|
||||
use crate::psq::{PSQ_MSG2_SIZE, psq_msg1_size, responder};
|
||||
@@ -259,10 +259,7 @@ mod tests {
|
||||
let (mut init_transport, mut resp_transport) = mock_transport();
|
||||
|
||||
// happy path
|
||||
let packet = LpPacket::new(
|
||||
LpHeader::new(123, 0, 1),
|
||||
LpMessage::new_opaque(b"foomp".to_vec()),
|
||||
);
|
||||
let packet = LpPacket::new(LpHeader::new(123, 0, 1, MessageType::Busy), LpMessage::Busy);
|
||||
|
||||
let ciphertext = encrypt_lp_packet(packet.clone(), &mut init_transport).unwrap();
|
||||
assert_eq!(packet.header().outer, ciphertext.outer_header());
|
||||
@@ -271,10 +268,7 @@ mod tests {
|
||||
assert_eq!(packet, plaintext);
|
||||
|
||||
// incomplete ciphertext
|
||||
let packet = LpPacket::new(
|
||||
LpHeader::new(123, 1, 1),
|
||||
LpMessage::new_opaque(b"foomp".to_vec()),
|
||||
);
|
||||
let packet = LpPacket::new(LpHeader::new(123, 1, 1, MessageType::Busy), LpMessage::Busy);
|
||||
let ciphertext2 = encrypt_lp_packet(packet, &mut init_transport).unwrap();
|
||||
let l = ciphertext2.ciphertext().len();
|
||||
let malformed_content = ciphertext2.ciphertext()[..l - 1].to_vec();
|
||||
@@ -283,10 +277,7 @@ mod tests {
|
||||
assert!(matches!(dec_err, LpError::PSQSessionFailure { .. }));
|
||||
|
||||
// too small buffer
|
||||
let packet = LpPacket::new(
|
||||
LpHeader::new(123, 1, 1),
|
||||
LpMessage::new_opaque(b"foomp".to_vec()),
|
||||
);
|
||||
let packet = LpPacket::new(LpHeader::new(123, 1, 1, MessageType::Busy), LpMessage::Busy);
|
||||
let ciphertext3 = encrypt_lp_packet(packet, &mut resp_transport).unwrap();
|
||||
let malformed = EncryptedLpPacket::new(ciphertext3.outer_header(), vec![]);
|
||||
let dec_err = decrypt_lp_packet(malformed, &mut init_transport).unwrap_err();
|
||||
|
||||
@@ -11,8 +11,8 @@ pub enum MalformedLpPacketError {
|
||||
#[error("provided insufficient data to fully deserialise the struct")]
|
||||
InsufficientData,
|
||||
|
||||
#[error("{0} is not a valid LpDataKind")]
|
||||
InvalidLpDataKind(u16),
|
||||
#[error("{0} is not a valid MessageType")]
|
||||
InvalidMessageType(u32),
|
||||
|
||||
#[error("invalid payload size: expected {expected}, got {actual}")]
|
||||
InvalidPayloadSize { expected: usize, actual: usize },
|
||||
@@ -27,7 +27,7 @@ pub enum MalformedLpPacketError {
|
||||
}
|
||||
|
||||
impl MalformedLpPacketError {
|
||||
pub fn invalid_data_kind(message_type: u16) -> Self {
|
||||
MalformedLpPacketError::InvalidLpDataKind(message_type)
|
||||
pub fn invalid_message_type(message_type: u32) -> Self {
|
||||
MalformedLpPacketError::InvalidMessageType(message_type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::packet::message::MessageType;
|
||||
use crate::packet::version;
|
||||
use crate::{packet::error::MalformedLpPacketError, peer_config::LpReceiverIndex};
|
||||
use bytes::{BufMut, BytesMut};
|
||||
// use nym_lp::peer_config::LpReceiverIndex;
|
||||
use tracing::warn;
|
||||
|
||||
/// Outer header (12 bytes) - always cleartext, used for routing.
|
||||
@@ -56,10 +58,11 @@ impl OuterHeader {
|
||||
pub struct InnerHeader {
|
||||
pub protocol_version: u8,
|
||||
pub reserved: [u8; 3],
|
||||
pub message_type: MessageType,
|
||||
}
|
||||
|
||||
impl InnerHeader {
|
||||
pub const SIZE: usize = 4; // protocol_version(1) + reserved(3)
|
||||
pub const SIZE: usize = 8; // protocol_version(1) + reserved(3) + message_type(4)
|
||||
|
||||
pub fn encode(&self, dst: &mut BytesMut) {
|
||||
// protocol version
|
||||
@@ -67,6 +70,9 @@ impl InnerHeader {
|
||||
|
||||
// reserved
|
||||
dst.put_slice(&self.reserved);
|
||||
|
||||
// message type
|
||||
dst.put_slice(&(self.message_type as u32).to_le_bytes());
|
||||
}
|
||||
|
||||
pub fn parse(src: &[u8]) -> Result<Self, MalformedLpPacketError> {
|
||||
@@ -98,9 +104,14 @@ impl InnerHeader {
|
||||
warn!("received non-zero reserved bytes. got: {reserved:?}");
|
||||
}
|
||||
|
||||
let msg_type_raw = u32::from_le_bytes([src[4], src[5], src[6], src[7]]);
|
||||
let message_type = MessageType::from_u32(msg_type_raw)
|
||||
.ok_or_else(|| MalformedLpPacketError::invalid_message_type(msg_type_raw))?;
|
||||
|
||||
Ok(InnerHeader {
|
||||
protocol_version,
|
||||
reserved,
|
||||
message_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -118,7 +129,12 @@ pub struct LpHeader {
|
||||
}
|
||||
|
||||
impl LpHeader {
|
||||
pub fn new(receiver_idx: LpReceiverIndex, counter: u64, protocol_version: u8) -> Self {
|
||||
pub fn new(
|
||||
receiver_idx: LpReceiverIndex,
|
||||
counter: u64,
|
||||
protocol_version: u8,
|
||||
message_type: MessageType,
|
||||
) -> Self {
|
||||
Self {
|
||||
outer: OuterHeader {
|
||||
receiver_idx,
|
||||
@@ -127,6 +143,7 @@ impl LpHeader {
|
||||
inner: InnerHeader {
|
||||
protocol_version,
|
||||
reserved: [0u8; 3],
|
||||
message_type,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,121 +2,111 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::packet::error::MalformedLpPacketError;
|
||||
use bytes::{BufMut, Bytes, BytesMut};
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
use std::fmt;
|
||||
use std::fmt::Display;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct LpMessageHeader {
|
||||
pub kind: LpMessageType,
|
||||
pub message_attributes: [u8; 14],
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum MessageType {
|
||||
/// The party is busy
|
||||
Busy = 0x0000,
|
||||
|
||||
/// Encrypted payload
|
||||
EncryptedData = 0x0001,
|
||||
|
||||
/// Receiver should forward this message via telescoping
|
||||
ForwardPacket = 0x0002,
|
||||
|
||||
/// Receiver index collision - client should retry with new index
|
||||
Collision = 0x0003,
|
||||
|
||||
/// Acknowledgment - gateway confirms receipt of message
|
||||
Ack = 0x0004,
|
||||
|
||||
/// General error
|
||||
Error = 0x00FF,
|
||||
}
|
||||
|
||||
impl LpMessageHeader {
|
||||
pub const SIZE: usize = 16; // message_kind(2) + message_attributes(14)
|
||||
impl MessageType {
|
||||
pub(crate) fn from_u32(value: u32) -> Option<Self> {
|
||||
MessageType::try_from(value).ok()
|
||||
}
|
||||
|
||||
pub fn new(kind: LpMessageType, message_attributes: [u8; 14]) -> Self {
|
||||
Self {
|
||||
kind,
|
||||
message_attributes,
|
||||
pub fn to_u32(&self) -> u32 {
|
||||
u32::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ApplicationData(pub Vec<u8>);
|
||||
|
||||
impl ApplicationData {
|
||||
pub fn new(bytes: Vec<u8>) -> Self {
|
||||
Self(bytes)
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
fn encode(&self, dst: &mut BytesMut) {
|
||||
dst.put_slice(&self.0);
|
||||
}
|
||||
|
||||
fn decode(bytes: &[u8]) -> Result<Self, MalformedLpPacketError> {
|
||||
Ok(ApplicationData(bytes.to_vec()))
|
||||
}
|
||||
}
|
||||
|
||||
/// General human-readable error message
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ErrorPacketData {
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl ErrorPacketData {
|
||||
pub fn new(message: impl Into<String>) -> Self {
|
||||
ErrorPacketData {
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_no_attributes(kind: LpMessageType) -> Self {
|
||||
Self {
|
||||
kind,
|
||||
message_attributes: [0; 14],
|
||||
fn len(&self) -> usize {
|
||||
// length-encoding + message
|
||||
4 + self.message.len()
|
||||
}
|
||||
|
||||
fn encode(&self, dst: &mut BytesMut) {
|
||||
dst.put_u32_le(self.message.len() as u32);
|
||||
dst.put_slice(self.message.as_bytes());
|
||||
}
|
||||
|
||||
fn decode(bytes: &[u8]) -> Result<Self, MalformedLpPacketError> {
|
||||
if bytes.len() < 4 {
|
||||
return Err(MalformedLpPacketError::DeserialisationFailure(format!(
|
||||
"Too few bytes to deserialise ErrorPacketData. got {}",
|
||||
bytes.len()
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode directly into a BytesMut buffer
|
||||
pub fn encode(&self, dst: &mut BytesMut) {
|
||||
dst.put_u16_le(self.kind as u16);
|
||||
dst.put_slice(&self.message_attributes);
|
||||
}
|
||||
|
||||
pub fn parse(src: &[u8]) -> Result<Self, MalformedLpPacketError> {
|
||||
if src.len() < Self::SIZE {
|
||||
return Err(MalformedLpPacketError::InsufficientData);
|
||||
let message_len = u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) as usize;
|
||||
if bytes[4..].len() != message_len {
|
||||
return Err(MalformedLpPacketError::DeserialisationFailure(format!(
|
||||
"Wrong number of bytes to deserialise ErrorPacketData. got {}. Expected {}",
|
||||
bytes.len(),
|
||||
4 + message_len
|
||||
)));
|
||||
}
|
||||
let raw_kind = u16::from_le_bytes([src[0], src[1]]);
|
||||
|
||||
let kind = LpMessageType::try_from(raw_kind)
|
||||
.map_err(|_| MalformedLpPacketError::invalid_data_kind(raw_kind))?;
|
||||
let message = String::from_utf8_lossy(&bytes[4..]).to_string();
|
||||
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let message_attributes = src[2..16].try_into().unwrap();
|
||||
Ok(Self {
|
||||
kind,
|
||||
message_attributes,
|
||||
})
|
||||
Ok(ErrorPacketData { message })
|
||||
}
|
||||
}
|
||||
|
||||
/// Represent application data being sent in Transport mode
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct LpMessage {
|
||||
pub header: LpMessageHeader,
|
||||
pub content: Bytes,
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for LpMessage {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.content
|
||||
}
|
||||
}
|
||||
|
||||
impl LpMessage {
|
||||
pub fn new(kind: LpMessageType, content: impl Into<Bytes>) -> Self {
|
||||
Self {
|
||||
header: LpMessageHeader::new_no_attributes(kind),
|
||||
content: content.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode(&self, dst: &mut BytesMut) {
|
||||
self.header.encode(dst);
|
||||
|
||||
dst.put_slice(&self.content);
|
||||
}
|
||||
|
||||
pub fn decode(src: &[u8]) -> Result<Self, MalformedLpPacketError> {
|
||||
let header = LpMessageHeader::parse(src)?;
|
||||
let content = src[LpMessageHeader::SIZE..].to_vec().into();
|
||||
|
||||
Ok(Self { header, content })
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> LpMessageType {
|
||||
self.header.kind
|
||||
}
|
||||
|
||||
pub fn new_opaque(content: impl Into<Bytes>) -> Self {
|
||||
Self::new(LpMessageType::Opaque, content)
|
||||
}
|
||||
|
||||
pub fn new_registration(data: impl Into<Bytes>) -> Self {
|
||||
Self::new(LpMessageType::Registration, data)
|
||||
}
|
||||
|
||||
pub fn new_forward(data: impl Into<Bytes>) -> Self {
|
||||
Self::new(LpMessageType::Forward, data)
|
||||
}
|
||||
|
||||
pub(crate) fn len(&self) -> usize {
|
||||
LpMessageHeader::SIZE + self.content.len()
|
||||
}
|
||||
}
|
||||
|
||||
/// Represent kind of application data being sent in Transport mode
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, IntoPrimitive, TryFromPrimitive)]
|
||||
#[repr(u16)]
|
||||
pub enum LpMessageType {
|
||||
Opaque = 0,
|
||||
Registration = 1,
|
||||
Forward = 2,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ExpectedResponseSize {
|
||||
/// We've sent a handshake message and expect response of predefined size
|
||||
@@ -173,6 +163,24 @@ impl ForwardPacketData {
|
||||
}
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
// 1 byte length of target lp address type
|
||||
// +
|
||||
// {4,16} target_lp_address IPv{4,6}
|
||||
// +
|
||||
// 2 bytes target_lp_address port
|
||||
// +
|
||||
// 4 bytes for expected response size
|
||||
// +
|
||||
// 4 bytes of length of inner packet bytes
|
||||
// +
|
||||
// inner_packet_bytes.len()
|
||||
match self.target_lp_address {
|
||||
SocketAddr::V4(_) => 1 + 4 + 2 + 4 + 4 + self.inner_packet_bytes.len(),
|
||||
SocketAddr::V6(_) => 1 + 16 + 2 + 4 + 4 + self.inner_packet_bytes.len(),
|
||||
}
|
||||
}
|
||||
|
||||
// 0 || [4B ipv4] || [2B port] || [4B res size] || [4B plen] || payload
|
||||
// 1 || [16B ipv6] || [2B port] || [4B res size] || [4B plen] || payload
|
||||
fn encode(&self, dst: &mut BytesMut) {
|
||||
@@ -253,3 +261,241 @@ impl ForwardPacketData {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum LpMessage {
|
||||
/// The party is busy
|
||||
Busy,
|
||||
|
||||
/// Application payload is being sent
|
||||
ApplicationData(ApplicationData),
|
||||
|
||||
/// Receiver should forward this message via telescoping
|
||||
ForwardPacket(ForwardPacketData),
|
||||
|
||||
/// Receiver index collision - client should retry with new receiver_index
|
||||
Collision,
|
||||
|
||||
/// Acknowledgment - gateway confirms receipt of message
|
||||
Ack,
|
||||
|
||||
/// An error has occurred
|
||||
Error(ErrorPacketData),
|
||||
}
|
||||
|
||||
impl From<ApplicationData> for LpMessage {
|
||||
fn from(value: ApplicationData) -> Self {
|
||||
LpMessage::ApplicationData(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ForwardPacketData> for LpMessage {
|
||||
fn from(value: ForwardPacketData) -> Self {
|
||||
LpMessage::ForwardPacket(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for LpMessage {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
LpMessage::Busy => write!(f, "Busy"),
|
||||
LpMessage::ApplicationData(_) => write!(f, "EncryptedData"),
|
||||
LpMessage::ForwardPacket(_) => write!(f, "ForwardPacket"),
|
||||
LpMessage::Collision => write!(f, "Collision"),
|
||||
LpMessage::Ack => write!(f, "Ack"),
|
||||
LpMessage::Error(_) => write!(f, "Error"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LpMessage {
|
||||
#[deprecated(note = "is it actually needed?")]
|
||||
pub fn payload(&self) -> &[u8] {
|
||||
match self {
|
||||
LpMessage::Busy => &[],
|
||||
LpMessage::ApplicationData(payload) => payload.0.as_slice(),
|
||||
LpMessage::ForwardPacket(_) => &[], // Structured data, serialized in encode_content
|
||||
LpMessage::Collision => &[],
|
||||
LpMessage::Ack => &[],
|
||||
LpMessage::Error(_) => &[], // Structured data, serialized in encode_content (?)
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(note = "is it actually needed?")]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
match self {
|
||||
LpMessage::Busy => true,
|
||||
LpMessage::ApplicationData(payload) => payload.0.is_empty(),
|
||||
LpMessage::ForwardPacket(_) => false, // Always has data
|
||||
LpMessage::Collision => true,
|
||||
LpMessage::Ack => true,
|
||||
LpMessage::Error(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
match self {
|
||||
LpMessage::Busy => 0,
|
||||
LpMessage::ApplicationData(payload) => payload.len(),
|
||||
LpMessage::ForwardPacket(payload) => payload.len(),
|
||||
LpMessage::Collision => 0,
|
||||
LpMessage::Ack => 0,
|
||||
LpMessage::Error(payload) => payload.len(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn typ(&self) -> MessageType {
|
||||
match self {
|
||||
LpMessage::Busy => MessageType::Busy,
|
||||
LpMessage::ApplicationData(_) => MessageType::EncryptedData,
|
||||
LpMessage::ForwardPacket(_) => MessageType::ForwardPacket,
|
||||
LpMessage::Collision => MessageType::Collision,
|
||||
LpMessage::Ack => MessageType::Ack,
|
||||
LpMessage::Error(_) => MessageType::Error,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode_content(&self, dst: &mut BytesMut) {
|
||||
match self {
|
||||
LpMessage::Busy => { /* No content */ }
|
||||
LpMessage::ApplicationData(payload) => payload.encode(dst),
|
||||
LpMessage::ForwardPacket(data) => data.encode(dst),
|
||||
LpMessage::Collision => { /* No content */ }
|
||||
LpMessage::Ack => { /* No content */ }
|
||||
LpMessage::Error(data) => data.encode(dst),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse message from its type and content bytes.
|
||||
///
|
||||
/// Used when decrypting outer-encrypted packets where the message type
|
||||
/// was encrypted along with the content.
|
||||
pub fn decode_content(
|
||||
content: &[u8],
|
||||
message_type: MessageType,
|
||||
) -> Result<Self, MalformedLpPacketError> {
|
||||
match message_type {
|
||||
MessageType::Busy => {
|
||||
content.ensure_empty()?;
|
||||
Ok(LpMessage::Busy)
|
||||
}
|
||||
MessageType::EncryptedData => Ok(LpMessage::ApplicationData(ApplicationData::decode(
|
||||
content,
|
||||
)?)),
|
||||
MessageType::ForwardPacket => Ok(LpMessage::ForwardPacket(ForwardPacketData::decode(
|
||||
content,
|
||||
)?)),
|
||||
MessageType::Collision => {
|
||||
content.ensure_empty()?;
|
||||
Ok(LpMessage::Collision)
|
||||
}
|
||||
MessageType::Ack => {
|
||||
content.ensure_empty()?;
|
||||
Ok(LpMessage::Ack)
|
||||
}
|
||||
MessageType::Error => Ok(LpMessage::Error(ErrorPacketData::decode(content)?)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait for improving readability to return error if bytes content is not empty
|
||||
trait EnsureEmptyContent {
|
||||
fn ensure_empty(&self) -> Result<(), MalformedLpPacketError>;
|
||||
}
|
||||
|
||||
impl EnsureEmptyContent for &[u8] {
|
||||
fn ensure_empty(&self) -> Result<(), MalformedLpPacketError> {
|
||||
if !self.is_empty() {
|
||||
return Err(MalformedLpPacketError::InvalidPayloadSize {
|
||||
expected: 0,
|
||||
actual: self.len(),
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::packet::{InnerHeader, LpHeader, LpPacket, OuterHeader};
|
||||
|
||||
#[test]
|
||||
fn encoding() {
|
||||
let message = LpMessage::ApplicationData(ApplicationData(vec![11u8; 124]));
|
||||
|
||||
let resp_header = LpHeader {
|
||||
outer: OuterHeader {
|
||||
receiver_idx: 456,
|
||||
counter: 123,
|
||||
},
|
||||
inner: InnerHeader {
|
||||
protocol_version: 1,
|
||||
reserved: [0u8; 3],
|
||||
message_type: MessageType::EncryptedData,
|
||||
},
|
||||
};
|
||||
|
||||
let packet = LpPacket {
|
||||
header: resp_header,
|
||||
message,
|
||||
};
|
||||
|
||||
// Just print packet for debug, will be captured in test output
|
||||
println!("{packet:?}");
|
||||
|
||||
// Verify message type
|
||||
assert!(matches!(packet.message.typ(), MessageType::EncryptedData));
|
||||
|
||||
// Verify correct data in message
|
||||
match &packet.message {
|
||||
LpMessage::ApplicationData(data) => {
|
||||
assert_eq!(*data, ApplicationData(vec![11u8; 124]));
|
||||
}
|
||||
_ => panic!("Wrong message type"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn forward_message_encoding() {
|
||||
let msg1 = ForwardPacketData {
|
||||
target_lp_address: "1.2.3.4:5678".parse().unwrap(),
|
||||
expected_response_size: ExpectedResponseSize::Transport,
|
||||
inner_packet_bytes: vec![],
|
||||
};
|
||||
|
||||
let msg2 = ForwardPacketData {
|
||||
target_lp_address: "1.2.3.4:5678".parse().unwrap(),
|
||||
expected_response_size: ExpectedResponseSize::Handshake(250),
|
||||
inner_packet_bytes: vec![42u8; 64],
|
||||
};
|
||||
|
||||
let msg3 = ForwardPacketData {
|
||||
target_lp_address: "[2001:db8::1]:8080".parse().unwrap(),
|
||||
expected_response_size: ExpectedResponseSize::Transport,
|
||||
inner_packet_bytes: vec![],
|
||||
};
|
||||
|
||||
let msg4 = ForwardPacketData {
|
||||
target_lp_address: "[2001:db8::1]:8080".parse().unwrap(),
|
||||
expected_response_size: ExpectedResponseSize::Handshake(250),
|
||||
inner_packet_bytes: vec![42u8; 64],
|
||||
};
|
||||
|
||||
let b = msg1.to_bytes();
|
||||
let msg1_r = ForwardPacketData::decode(&b).unwrap();
|
||||
assert_eq!(msg1_r, msg1);
|
||||
|
||||
let b = msg2.to_bytes();
|
||||
let msg2_r = ForwardPacketData::decode(&b).unwrap();
|
||||
assert_eq!(msg2_r, msg2);
|
||||
|
||||
let b = msg3.to_bytes();
|
||||
let msg3_r = ForwardPacketData::decode(&b).unwrap();
|
||||
assert_eq!(msg3_r, msg3);
|
||||
|
||||
let b = msg4.to_bytes();
|
||||
let msg4_r = ForwardPacketData::decode(&b).unwrap();
|
||||
assert_eq!(msg4_r, msg4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::fmt::{Debug, Formatter};
|
||||
|
||||
pub use error::MalformedLpPacketError;
|
||||
pub use header::{InnerHeader, LpHeader, OuterHeader};
|
||||
pub use message::{ForwardPacketData, LpMessage};
|
||||
pub use message::{ApplicationData, ForwardPacketData, LpMessage, MessageType};
|
||||
|
||||
pub mod error;
|
||||
pub mod header;
|
||||
@@ -78,7 +78,7 @@ impl EncryptedLpPacket {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct LpPacket {
|
||||
pub(crate) header: LpHeader,
|
||||
pub(crate) message: LpMessage,
|
||||
@@ -95,6 +95,10 @@ impl LpPacket {
|
||||
Self { header, message }
|
||||
}
|
||||
|
||||
pub fn typ(&self) -> MessageType {
|
||||
self.message.typ()
|
||||
}
|
||||
|
||||
pub fn message(&self) -> &LpMessage {
|
||||
&self.message
|
||||
}
|
||||
@@ -115,6 +119,8 @@ impl LpPacket {
|
||||
|
||||
pub(crate) fn dbg_encode(&self, dst: &mut BytesMut) {
|
||||
self.header.dbg_encode(dst);
|
||||
self.message.encode(dst)
|
||||
|
||||
dst.put_slice(&(self.message.typ() as u16).to_le_bytes());
|
||||
self.message.encode_content(dst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! This module implements session management functionality, including replay protection
|
||||
|
||||
use crate::codec::{decrypt_lp_packet, encrypt_lp_packet};
|
||||
use crate::packet::{EncryptedLpPacket, LpHeader, LpMessage, LpPacket};
|
||||
use crate::packet::{ApplicationData, EncryptedLpPacket, LpHeader, LpMessage, LpPacket};
|
||||
use crate::peer::{LpLocalPeer, LpRemotePeer};
|
||||
use crate::peer_config::LpReceiverIndex;
|
||||
use crate::psq::{
|
||||
@@ -174,7 +174,12 @@ impl LpSession {
|
||||
|
||||
pub fn next_packet(&mut self, message: LpMessage) -> Result<LpPacket, LpError> {
|
||||
let counter = self.next_counter();
|
||||
let header = LpHeader::new(self.receiver_index(), counter, self.protocol_version);
|
||||
let header = LpHeader::new(
|
||||
self.receiver_index(),
|
||||
counter,
|
||||
self.protocol_version,
|
||||
message.typ(),
|
||||
);
|
||||
let packet = LpPacket::new(header, message);
|
||||
Ok(packet)
|
||||
}
|
||||
@@ -250,9 +255,9 @@ impl LpSession {
|
||||
/// * `Err(LpError)` if the session is not in transport mode or encryption fails.
|
||||
pub(crate) fn encrypt_application_data(
|
||||
&mut self,
|
||||
data: LpMessage,
|
||||
data: Vec<u8>,
|
||||
) -> Result<EncryptedLpPacket, LpError> {
|
||||
let packet = self.next_packet(data)?;
|
||||
let packet = self.next_packet(LpMessage::ApplicationData(ApplicationData::new(data)))?;
|
||||
encrypt_lp_packet(packet, &mut self.active_transport)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::packet::{EncryptedLpPacket, LpMessage};
|
||||
use crate::state_machine::{LpAction, LpInput, LpStateBare};
|
||||
use crate::packet::EncryptedLpPacket;
|
||||
use crate::state_machine::{LpAction, LpData, LpInput, LpStateBare};
|
||||
use crate::{LpError, SessionManager, SessionsMock};
|
||||
use nym_kkt_ciphersuite::{IntoEnumIterator, KEM};
|
||||
|
||||
@@ -9,7 +9,7 @@ mod tests {
|
||||
trait ActionExtract {
|
||||
fn ciphertext(self) -> EncryptedLpPacket;
|
||||
|
||||
fn data(self) -> LpMessage;
|
||||
fn data(self) -> LpData;
|
||||
}
|
||||
|
||||
impl ActionExtract for LpAction {
|
||||
@@ -21,7 +21,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn data(self) -> LpMessage {
|
||||
fn data(self) -> LpData {
|
||||
if let LpAction::DeliverData(data) = self {
|
||||
data
|
||||
} else {
|
||||
@@ -54,7 +54,7 @@ mod tests {
|
||||
// --- A sends to B ---
|
||||
let plaintext_a = format!("A->B Message {i}").into_bytes();
|
||||
let ciphertext_a = session_manager_1
|
||||
.send_data(peer_a_sm, LpMessage::new_opaque(plaintext_a.clone()))
|
||||
.send_data(peer_a_sm, LpData::new_opaque(plaintext_a.clone()))
|
||||
.unwrap()
|
||||
.ciphertext();
|
||||
|
||||
@@ -69,7 +69,7 @@ mod tests {
|
||||
// --- B sends to A ---
|
||||
let plaintext_b = format!("B->A Message {i}").into_bytes();
|
||||
let ciphertext_b = session_manager_2
|
||||
.send_data(peer_b_sm, LpMessage::new_opaque(plaintext_b.clone()))
|
||||
.send_data(peer_b_sm, LpData::new_opaque(plaintext_b.clone()))
|
||||
.unwrap()
|
||||
.ciphertext();
|
||||
|
||||
@@ -195,10 +195,8 @@ mod tests {
|
||||
|
||||
// --- 3. Simulate Data Transfer via process_input ---
|
||||
println!("Starting data transfer simulation via process_input...");
|
||||
let plaintext_a_to_b =
|
||||
LpMessage::new_opaque(b"Hello from A via process_input!".to_vec());
|
||||
let plaintext_b_to_a =
|
||||
LpMessage::new_opaque(b"Hello from B via process_input!".to_vec());
|
||||
let plaintext_a_to_b = LpData::new_opaque(b"Hello from A via process_input!".to_vec());
|
||||
let plaintext_b_to_a = LpData::new_opaque(b"Hello from B via process_input!".to_vec());
|
||||
|
||||
// --- A sends to B ---
|
||||
println!(" A sends to B");
|
||||
@@ -274,8 +272,8 @@ mod tests {
|
||||
println!("Testing out-of-order reception via process_input...");
|
||||
|
||||
// A prepares N+1 then N
|
||||
let data_n_plus_1 = LpMessage::new_opaque(b"Message N+1".to_vec());
|
||||
let data_n = LpMessage::new_opaque(b"Message N".to_vec());
|
||||
let data_n_plus_1 = LpData::new_opaque(b"Message N+1".to_vec());
|
||||
let data_n = LpData::new_opaque(b"Message N".to_vec());
|
||||
|
||||
let action_send_n1 = session_manager_1
|
||||
.process_input(session_id, LpInput::SendData(data_n_plus_1.clone()))
|
||||
@@ -346,7 +344,7 @@ mod tests {
|
||||
// Further actions on A fail
|
||||
let send_after_close_a = session_manager_1.process_input(
|
||||
session_id,
|
||||
LpInput::SendData(LpMessage::new_opaque(b"fail".to_vec())),
|
||||
LpInput::SendData(LpData::new_opaque(b"fail".to_vec())),
|
||||
);
|
||||
assert!(send_after_close_a.is_err());
|
||||
assert!(matches!(
|
||||
@@ -368,7 +366,7 @@ mod tests {
|
||||
// Further actions on B fail
|
||||
let send_after_close_b = session_manager_2.process_input(
|
||||
session_id,
|
||||
LpInput::SendData(LpMessage::new_opaque(b"fail".to_vec())),
|
||||
LpInput::SendData(LpData::new_opaque(b"fail".to_vec())),
|
||||
);
|
||||
assert!(send_after_close_b.is_err());
|
||||
assert!(matches!(
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
//! This module implements session lifecycle management functionality, handling
|
||||
//! creation, retrieval, and storage of sessions.
|
||||
|
||||
use crate::packet::{EncryptedLpPacket, LpMessage};
|
||||
use crate::packet::EncryptedLpPacket;
|
||||
use crate::peer_config::LpReceiverIndex;
|
||||
use crate::state_machine::{LpAction, LpInput, LpStateBare};
|
||||
use crate::state_machine::{LpAction, LpData, LpInput, LpStateBare};
|
||||
use crate::{LpError, LpSession, LpStateMachine};
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -44,11 +44,7 @@ impl SessionManager {
|
||||
self.with_state_machine_mut(lp_id, |sm| sm.process_input(input).transpose())?
|
||||
}
|
||||
|
||||
pub fn send_data(
|
||||
&mut self,
|
||||
lp_id: LpReceiverIndex,
|
||||
data: LpMessage,
|
||||
) -> Result<LpAction, LpError> {
|
||||
pub fn send_data(&mut self, lp_id: LpReceiverIndex, data: LpData) -> Result<LpAction, LpError> {
|
||||
self.process_input(lp_id, LpInput::SendData(data))?
|
||||
.ok_or(LpError::NotInTransport)
|
||||
}
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
//! State machine ensures protocol steps execute in correct order. Invalid transitions
|
||||
//! return LpError, preventing protocol violations.
|
||||
|
||||
use crate::packet::EncryptedLpPacket;
|
||||
use crate::packet::message::LpMessage;
|
||||
use crate::packet::{EncryptedLpPacket, LpMessage};
|
||||
use crate::peer_config::LpReceiverIndex;
|
||||
use crate::session::SessionId;
|
||||
use crate::{LpError, session::LpSession};
|
||||
use bytes::{Buf, Bytes};
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
use std::mem;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -57,7 +58,7 @@ pub enum LpInput {
|
||||
ReceivePacket(EncryptedLpPacket),
|
||||
|
||||
/// Application wants to send data (only valid in Transport state).
|
||||
SendData(LpMessage),
|
||||
SendData(LpData),
|
||||
|
||||
/// Close the connection.
|
||||
Close,
|
||||
@@ -70,12 +71,81 @@ pub enum LpAction {
|
||||
SendPacket(EncryptedLpPacket),
|
||||
|
||||
/// Deliver decrypted application data received from the peer.
|
||||
DeliverData(LpMessage),
|
||||
DeliverData(LpData),
|
||||
|
||||
/// Inform the environment that the connection is closed.
|
||||
ConnectionClosed,
|
||||
}
|
||||
|
||||
/// Represent application data being sent in Transport mode
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct LpData {
|
||||
pub kind: LpDataKind,
|
||||
pub content: Bytes,
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for LpData {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.content
|
||||
}
|
||||
}
|
||||
|
||||
impl LpData {
|
||||
pub fn new(kind: LpDataKind, content: impl Into<Bytes>) -> Self {
|
||||
Self {
|
||||
kind,
|
||||
content: content.into(),
|
||||
}
|
||||
}
|
||||
pub fn new_opaque(content: impl Into<Bytes>) -> Self {
|
||||
Self::new(LpDataKind::Opaque, content)
|
||||
}
|
||||
|
||||
pub fn new_registration(data: impl Into<Bytes>) -> Self {
|
||||
Self::new(LpDataKind::Registration, data)
|
||||
}
|
||||
|
||||
pub fn new_forward(data: impl Into<Bytes>) -> Self {
|
||||
Self::new(LpDataKind::Forward, data)
|
||||
}
|
||||
|
||||
pub fn to_vec(self) -> Vec<u8> {
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LpData> for Vec<u8> {
|
||||
fn from(data: LpData) -> Self {
|
||||
let mut out = Vec::with_capacity(data.content.len() + 1);
|
||||
out.push(data.kind as u8);
|
||||
out.extend_from_slice(data.content.as_ref());
|
||||
out
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Vec<u8>> for LpData {
|
||||
type Error = LpError;
|
||||
|
||||
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
|
||||
let kind = LpDataKind::try_from(value[0]).map_err(|_| {
|
||||
LpError::DeserializationError(format!("unknown data type: {}", value[0]))
|
||||
})?;
|
||||
let mut content = Bytes::from(value);
|
||||
content.advance(1);
|
||||
|
||||
Ok(LpData::new(kind, content))
|
||||
}
|
||||
}
|
||||
|
||||
/// Represent kind of application data being sent in Transport mode
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, IntoPrimitive, TryFromPrimitive)]
|
||||
#[repr(u8)]
|
||||
pub enum LpDataKind {
|
||||
Opaque = 0,
|
||||
Registration = 1,
|
||||
Forward = 2,
|
||||
}
|
||||
|
||||
/// The Lewes Protocol State Machine.
|
||||
pub struct LpStateMachine {
|
||||
pub state: LpState,
|
||||
@@ -164,10 +234,31 @@ impl LpStateMachine {
|
||||
return (LpState::Transport(state), Some(Err(e)));
|
||||
}
|
||||
|
||||
// 4. deliver the message
|
||||
let message = packet.message;
|
||||
let result_action = Some(Ok(LpAction::DeliverData(message)));
|
||||
(LpState::Transport(state), result_action)
|
||||
// Check message type
|
||||
match packet.into_message() {
|
||||
// Normal encrypted data
|
||||
LpMessage::ApplicationData(payload) => {
|
||||
// Deliver data
|
||||
match payload.0.try_into() {
|
||||
Ok(data) => {
|
||||
let result_action = Some(Ok(LpAction::DeliverData(data)));
|
||||
(LpState::Transport(state), result_action)
|
||||
}
|
||||
Err(e) => {
|
||||
let reason = e.to_string();
|
||||
(LpState::Closed { reason }, Some(Err(e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
other => {
|
||||
// Unexpected message type in Transport state
|
||||
let err = LpError::InvalidStateTransition {
|
||||
state: "Transport".to_string(),
|
||||
input: format!("Unexpected message type: {other}"),
|
||||
};
|
||||
(LpState::Transport(state), Some(Err(err)))
|
||||
}
|
||||
}
|
||||
}
|
||||
LpInput::SendData(data) => {
|
||||
// Encrypt and send application data
|
||||
@@ -248,9 +339,9 @@ impl LpStateMachine {
|
||||
fn prepare_data_packet(
|
||||
&self,
|
||||
session: &mut LpSession,
|
||||
data: LpMessage,
|
||||
data: LpData,
|
||||
) -> Result<EncryptedLpPacket, LpError> {
|
||||
session.encrypt_application_data(data)
|
||||
session.encrypt_application_data(data.to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +386,7 @@ mod tests {
|
||||
|
||||
// --- Transport Phase ---
|
||||
println!("--- Step 1: Initiator sends data ---");
|
||||
let data_to_send_1 = LpMessage::new_opaque(b"hello responder".to_vec());
|
||||
let data_to_send_1 = LpData::new_opaque(b"hello responder".to_vec());
|
||||
let init_actions_4 = initiator.process_input(LpInput::SendData(data_to_send_1.clone()));
|
||||
let data_packet_1 = if let Some(Ok(LpAction::SendPacket(packet))) = init_actions_4 {
|
||||
packet.clone()
|
||||
@@ -314,7 +405,7 @@ mod tests {
|
||||
assert_eq!(resp_data_1, data_to_send_1);
|
||||
|
||||
println!("--- Step 3: Responder sends data ---");
|
||||
let data_to_send_2 = LpMessage::new_opaque(b"hello initiator".to_vec());
|
||||
let data_to_send_2 = LpData::new_opaque(b"hello initiator".to_vec());
|
||||
let resp_actions_6 = responder.process_input(LpInput::SendData(data_to_send_2.clone()));
|
||||
let data_packet_2 = if let Some(Ok(LpAction::SendPacket(packet))) = resp_actions_6 {
|
||||
packet.clone()
|
||||
|
||||
@@ -57,37 +57,6 @@ This page displays a full list of all the changes during our release cycle from
|
||||
|
||||
<VarInfo />
|
||||
|
||||
## `v2026.4-quark`
|
||||
|
||||
- [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2026.4-quark)
|
||||
- [`nym-node`](nodes/nym-node.mdx) version `1.26.0`
|
||||
|
||||
```sh
|
||||
nym-node
|
||||
Binary Name: nym-node
|
||||
Build Timestamp: 2026-02-24T13:43:24.098285047Z
|
||||
Build Version: 1.26.0
|
||||
Commit SHA: a2081af6038ef3ef40b3d9368299d2676a2fbb6a
|
||||
Commit Date: 2026-02-24T12:02:35.000000000+01:00
|
||||
Commit Branch: HEAD
|
||||
rustc Version: 1.91.1
|
||||
rustc Channel: stable
|
||||
cargo Profile: release
|
||||
```
|
||||
|
||||
### Operator & Developer Updates
|
||||
|
||||
### Features
|
||||
|
||||
- [Stateless handshake improvements for LP Gateway](https://github.com/nymtech/nym/pull/6437)
|
||||
- [HTTP & DNS improvements](https://github.com/nymtech/nym/pull/6423)
|
||||
- [Endpoint support for exit gateway IPs](https://github.com/nymtech/nym/pull/6418)
|
||||
|
||||
### Tools
|
||||
|
||||
- **Diagnostic Tool** - a standalone binary for network diagnostics. It performs DNS, HTTP, and gateway connectivity tests, helping developers identify connectivity issues and monitor network performance. It can also be run via the daemon CLI. Read the full guide [here](https://nym.com/docs/developers/tools/diagnostic-tool).
|
||||
- **Socks5 Score Calculation** - performed by the Gateway probe, which tests `nym-node --mode exit-gateway` instances over Socks5. The probe assigns a latency-based rating: high, medium, low, or offline. Full guide [here](https://nym.com/docs/operators/performance-and-testing#socks5-score-calculation-process).
|
||||
|
||||
## `v2026.3-parmigiano`
|
||||
- [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2026.3-parmigiano)
|
||||
- [`nym-node`](nodes/nym-node.mdx) version `1.25.0`
|
||||
@@ -105,9 +74,9 @@ rustc Channel: stable
|
||||
cargo Profile: release
|
||||
```
|
||||
|
||||
### Operator & Developer Updates
|
||||
### Key updates for operators include:
|
||||
|
||||
### Features
|
||||
LP Gateway and Client fixes:
|
||||
|
||||
- [Registration client now properly supports fallback](https://github.com/nymtech/nym/pull/6419)
|
||||
- [Exposed WireGuard PSK for vpn-client](https://github.com/nymtech/nym/pull/6411)
|
||||
@@ -116,14 +85,28 @@ cargo Profile: release
|
||||
|
||||
Note: This code is currently deactivated and doesn’t involve any changes for operators right now, but it will in the future.
|
||||
|
||||
### Bugfix
|
||||
Mixnet & Networking Enhancements:
|
||||
|
||||
- [NS API Socks5 support](https://github.com/nymtech/nym/pull/6361)
|
||||
- [Two-step dvpn registration flow](https://github.com/nymtech/nym/pull/6386)
|
||||
- [DVPN PSK injection](https://github.com/nymtech/nym/pull/6378)
|
||||
|
||||
Security & Encoding Improvements:
|
||||
|
||||
- [Hex-encoding for LP key digests](https://github.com/nymtech/nym/pull/6394)
|
||||
- [Encrypted KKT](https://github.com/nymtech/nym/pull/6331)
|
||||
- [Reject packets with incompatible versions](https://github.com/nymtech/nym/pull/6326)
|
||||
|
||||
Bugfixes & Quality-of-Life:
|
||||
|
||||
- [Share IP allocation fixes](https://github.com/nymtech/nym/pull/6395)
|
||||
- [Mixnet registration fixes](https://github.com/nymtech/nym/pull/6356)
|
||||
- [Small QoL changes](https://github.com/nymtech/nym/pull/6340)
|
||||
|
||||
### Refactors & Maintenance
|
||||
Chores & Maintenance:
|
||||
|
||||
- [Cleanup x25519/ed22519 usage](https://github.com/nymtech/nym/pull/6335)
|
||||
- [Upgrade to def_guard_wireguard v0.8.0](https://github.com/nymtech/nym/pull/6315)
|
||||
|
||||
## `v2026.2-oscypek`
|
||||
|
||||
@@ -155,7 +138,7 @@ Secondly, the outcome of [NIP-7: Nym Exit Policy Update - Opening Ports for Stea
|
||||
|
||||
This release brings changes which would lead into a *foreign constraint bug* if operators just switched binaries and restarted the node. To prevent it we need to do a little `sqlite` tweak on the node database.
|
||||
|
||||
To simplify this, we made **a build in command, which operators must run after getting the new binary, but before restarting the node.**
|
||||
To simplify this, we made **a build in command, which operators must run after getting the new binary, but beofre restarting the node.**
|
||||
|
||||
These are the steps to follow:
|
||||
|
||||
@@ -179,7 +162,7 @@ chmod +x nym-node
|
||||
```sh
|
||||
systemctl restart nym-node
|
||||
```
|
||||
- Additionally look for status or service journal
|
||||
- Additionaly look for starus or serivice journal
|
||||
```sh
|
||||
service nym-node status
|
||||
# or
|
||||
@@ -1319,7 +1302,7 @@ cargo Profile: release
|
||||
|
||||
- [Listen for shutdown signals during nym-node startup](https://github.com/nymtech/nym/pull/5879): This is to avoid situation where the process can't be killed without 'kill -9' because the logic to listen to shutdown signals hasn't been hit yet
|
||||
|
||||
### Bugfix
|
||||
### Bugfixes
|
||||
|
||||
- [Don't allow mixnode running in exit mode](https://github.com/nymtech/nym/pull/5898)
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ Yes, there are..
|
||||
|
||||
**Built by community**
|
||||
|
||||
* [SpectreDAO Explorer](https://explorer.nym.spectredao.net/dashboard)
|
||||
* [Nymesis](https://nymesis.vercel.app)
|
||||
* [ExploreNYM](https://explorenym.net/)
|
||||
* [Mixplorer](https://mixplorer.xyz/)
|
||||
|
||||
|
||||
### Which VPS providers would you recommend?
|
||||
|
||||
@@ -21,16 +21,17 @@ This documentation page provides a guide on how to set up and run a [NYM NODE](.
|
||||
```sh
|
||||
nym-node
|
||||
Binary Name: nym-node
|
||||
Build Timestamp: 2026-02-24T13:43:24.098285047Z
|
||||
Build Version: 1.26.0
|
||||
Commit SHA: a2081af6038ef3ef40b3d9368299d2676a2fbb6a
|
||||
Commit Date: 2026-02-24T12:02:35.000000000+01:00
|
||||
Build Timestamp: 2026-01-27T14:54:15.579821601Z
|
||||
Build Version: 1.24.0
|
||||
Commit SHA: 83bf9dc7cc2b01f65cab671733f2bf6c3abd471d
|
||||
Commit Date: 2026-01-27T15:46:52.000000000+01:00
|
||||
Commit Branch: HEAD
|
||||
rustc Version: 1.91.1
|
||||
rustc Channel: stable
|
||||
cargo Profile: release
|
||||
```
|
||||
|
||||
|
||||
Detailed version archive and release notes is documented [here](../../changelog.mdx).
|
||||
|
||||
{/* COMMENTING THIS OUT ASS WE HAVE TO FIGURE OUT HOW TO SHOW THE LATEST VERSION FROM MASTER BRANCH
|
||||
|
||||
@@ -393,11 +393,10 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_basic_lp_entry_registration() -> anyhow::Result<()> {
|
||||
// nym_test_utils::helpers::setup_test_logger();
|
||||
|
||||
for kem in KEM::iter() {
|
||||
let ciphersuite = Ciphersuite::default().with_kem(kem);
|
||||
|
||||
// nym_test_utils::helpers::setup_test_logger();
|
||||
// initialise random, but deterministic, keys, addresses, etc. for the parties
|
||||
let mut client_rng = u64_seeded_rng_09(0);
|
||||
let mut gateway_rng = u64_seeded_rng_09(1);
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
[package]
|
||||
name = "nym-api"
|
||||
license = "GPL-3.0"
|
||||
version = "1.1.75"
|
||||
version = "1.1.74"
|
||||
authors.workspace = true
|
||||
edition = "2021"
|
||||
rust-version.workspace = true
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-node-status-agent"
|
||||
version = "1.1.2-test"
|
||||
version = "1.1.2"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
@@ -62,12 +62,6 @@ pub(crate) async fn run_probe(
|
||||
let json_str = extract_json_from_log(&log);
|
||||
if json_str.is_empty() {
|
||||
tracing::error!("Failed to extract JSON from probe output");
|
||||
let preview: String = log.chars().take(400).collect();
|
||||
tracing::error!(
|
||||
"Probe output preview (first {} chars): {}",
|
||||
preview.len(),
|
||||
preview
|
||||
);
|
||||
} else {
|
||||
match serde_json::from_str::<serde_json::Value>(&json_str) {
|
||||
Ok(json) => {
|
||||
@@ -89,12 +83,6 @@ pub(crate) async fn run_probe(
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to parse probe output as JSON: {e}");
|
||||
let preview: String = json_str.chars().take(400).collect();
|
||||
tracing::error!(
|
||||
"Extracted JSON preview (first {} chars): {}",
|
||||
preview.len(),
|
||||
preview
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,13 +104,9 @@ impl GwProbe {
|
||||
match command.spawn() {
|
||||
Ok(child) => {
|
||||
if let Ok(output) = child.wait_with_output() {
|
||||
let err = String::from_utf8_lossy(&output.stderr);
|
||||
if !err.trim().is_empty() {
|
||||
tracing::info!("Probe stderr:\n{}", err);
|
||||
}
|
||||
|
||||
if !output.status.success() {
|
||||
let out = String::from_utf8_lossy(&output.stdout);
|
||||
let err = String::from_utf8_lossy(&output.stderr);
|
||||
tracing::error!("Probe exited with {:?}:\n{}\n{}", output.status, out, err);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-node-status-api"
|
||||
version = "4.1.0-test"
|
||||
version = "4.1.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-node"
|
||||
version = "1.27.0"
|
||||
version = "1.26.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::node::lp::LpReceiverIndex;
|
||||
use nym_lp::packet::message::LpMessageType;
|
||||
use nym_lp::state_machine::LpAction;
|
||||
use nym_lp::state_machine::{LpAction, LpDataKind};
|
||||
use nym_lp::transport::LpTransportError;
|
||||
use nym_lp::{LpError, packet::MalformedLpPacketError};
|
||||
use std::net::SocketAddr;
|
||||
@@ -45,7 +44,7 @@ pub enum LpHandlerError {
|
||||
MalformedLpPacket(#[from] MalformedLpPacketError),
|
||||
|
||||
#[error("received payload type of an unexpected type: {typ:?}")]
|
||||
UnexpectedLpPayload { typ: LpMessageType },
|
||||
UnexpectedLpPayload { typ: LpDataKind },
|
||||
|
||||
#[error("timed out while attempting to send to/receive from the connection")]
|
||||
ConnectionTimeout,
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
use super::{LpHandlerState, LpReceiverIndex, TimestampedState};
|
||||
use crate::node::lp::error::LpHandlerError;
|
||||
use dashmap::mapref::one::RefMut;
|
||||
use nym_lp::packet::message::LpMessageType;
|
||||
use nym_lp::packet::{EncryptedLpPacket, ForwardPacketData, LpMessage};
|
||||
use nym_lp::state_machine::{LpAction, LpInput};
|
||||
use nym_lp::packet::{EncryptedLpPacket, ForwardPacketData};
|
||||
use nym_lp::state_machine::{LpAction, LpData, LpDataKind, LpInput};
|
||||
use nym_lp::transport::LpHandshakeChannel;
|
||||
use nym_lp::transport::traits::LpTransportChannel;
|
||||
use nym_lp::{LpSession, LpStateMachine, packet::message::ExpectedResponseSize};
|
||||
@@ -302,14 +301,13 @@ where
|
||||
async fn handle_decrypted_payload(
|
||||
&mut self,
|
||||
receiver_idx: LpReceiverIndex,
|
||||
decrypted_data: LpMessage,
|
||||
decrypted_data: LpData,
|
||||
) -> Result<(), LpHandlerError> {
|
||||
let remote = self.remote_addr;
|
||||
|
||||
let header = decrypted_data.header;
|
||||
let bytes = decrypted_data.content;
|
||||
match header.kind {
|
||||
LpMessageType::Registration => {
|
||||
match decrypted_data.kind {
|
||||
LpDataKind::Registration => {
|
||||
let request = LpRegistrationRequest::try_deserialise(&bytes)
|
||||
.map_err(|source| LpHandlerError::MalformedRegistrationRequest { source })?;
|
||||
|
||||
@@ -321,13 +319,13 @@ where
|
||||
self.handle_registration_request(receiver_idx, request)
|
||||
.await
|
||||
}
|
||||
LpMessageType::Forward => {
|
||||
LpDataKind::Forward => {
|
||||
let forward_data = ForwardPacketData::decode(&bytes)?;
|
||||
|
||||
self.handle_forwarding_request(receiver_idx, forward_data)
|
||||
.await
|
||||
}
|
||||
typ @ LpMessageType::Opaque => {
|
||||
typ @ LpDataKind::Opaque => {
|
||||
// Neither registration nor forwarding - unknown payload type
|
||||
warn!(
|
||||
"Unknown transport payload type from {remote} (receiver_idx={receiver_idx}). dropping {} bytes",
|
||||
@@ -343,14 +341,14 @@ where
|
||||
async fn send_response_packet(
|
||||
&mut self,
|
||||
serialised_response: Vec<u8>,
|
||||
response_kind: LpMessageType,
|
||||
response_kind: LpDataKind,
|
||||
) -> Result<(), LpHandlerError> {
|
||||
let mut state_entry = self.state_entry_mut()?;
|
||||
|
||||
// Access session via state machine for subsession support
|
||||
let state_machine = &mut state_entry.value_mut().state;
|
||||
|
||||
let wrapped_lp_data = LpMessage::new(response_kind, serialised_response);
|
||||
let wrapped_lp_data = LpData::new(response_kind, serialised_response);
|
||||
|
||||
// Process packet through state machine
|
||||
let action = state_machine
|
||||
@@ -380,7 +378,7 @@ where
|
||||
.serialise()
|
||||
.map_err(|source| LpHandlerError::MalformedRegistrationRequest { source })?;
|
||||
|
||||
self.send_response_packet(response_bytes, LpMessageType::Registration)
|
||||
self.send_response_packet(response_bytes, LpDataKind::Registration)
|
||||
.await?;
|
||||
|
||||
match response.status {
|
||||
@@ -417,7 +415,7 @@ where
|
||||
// Forward the packet to the target gateway and retrieve its response
|
||||
let response_bytes = self.handle_forward_packet(forward_data).await?;
|
||||
|
||||
self.send_response_packet(response_bytes, LpMessageType::Forward)
|
||||
self.send_response_packet(response_bytes, LpDataKind::Forward)
|
||||
.await?;
|
||||
|
||||
debug!(
|
||||
@@ -752,7 +750,7 @@ mod tests {
|
||||
|
||||
// Send a valid packet from client side
|
||||
let LpAction::SendPacket(packet) = init_sm
|
||||
.send_data(id, LpMessage::new_opaque(b"foomp".to_vec()))
|
||||
.send_data(id, LpData::new_opaque(b"foomp".to_vec()))
|
||||
.unwrap()
|
||||
else {
|
||||
panic!("illegal state")
|
||||
@@ -788,7 +786,7 @@ mod tests {
|
||||
let (mut stream, _) = listener.accept().await.unwrap();
|
||||
|
||||
let LpAction::SendPacket(packet) = resp_sm
|
||||
.send_data(id, LpMessage::new_opaque(b"foomp".to_vec()))
|
||||
.send_data(id, LpData::new_opaque(b"foomp".to_vec()))
|
||||
.unwrap()
|
||||
else {
|
||||
panic!("illegal state")
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
use nym_lp::LpError;
|
||||
use nym_lp::packet::MalformedLpPacketError;
|
||||
use nym_lp::packet::message::LpMessageType;
|
||||
use nym_lp::state_machine::LpAction;
|
||||
use nym_lp::state_machine::{LpAction, LpDataKind};
|
||||
use nym_lp::transport::LpTransportError;
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -46,7 +45,7 @@ pub enum LpClientError {
|
||||
MalformedLpPacket(#[from] MalformedLpPacketError),
|
||||
|
||||
#[error("received payload type of an unexpected type: {typ:?}")]
|
||||
UnexpectedLpPayload { typ: LpMessageType },
|
||||
UnexpectedLpPayload { typ: LpDataKind },
|
||||
|
||||
#[error("timed out while attempting to finish the KKT/PSQ handshake")]
|
||||
HandshakeTimeout,
|
||||
|
||||
@@ -4,24 +4,23 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use crate::LpClientError;
|
||||
use nym_lp::packet::message::LpMessageType;
|
||||
use nym_lp::packet::{ForwardPacketData, LpMessage};
|
||||
use nym_lp::packet::ForwardPacketData;
|
||||
use nym_lp::peer::LpRemotePeer;
|
||||
use nym_lp::state_machine::{LpAction, LpInput};
|
||||
use nym_lp::state_machine::{LpAction, LpData, LpDataKind, LpInput};
|
||||
use nym_registration_common::{
|
||||
LpRegistrationRequest, LpRegistrationResponse, NymNodeLPInformation,
|
||||
};
|
||||
|
||||
pub(crate) trait LpDataSendExt {
|
||||
fn to_lp_data(&self) -> Result<LpMessage, LpClientError>;
|
||||
fn to_lp_data(&self) -> Result<LpData, LpClientError>;
|
||||
}
|
||||
|
||||
pub(crate) trait LpDataDeliverExt: Sized {
|
||||
fn from_lp_data(data: LpMessage) -> Result<Self, LpClientError>;
|
||||
fn from_lp_data(data: LpData) -> Result<Self, LpClientError>;
|
||||
}
|
||||
|
||||
impl LpDataSendExt for LpRegistrationRequest {
|
||||
fn to_lp_data(&self) -> Result<LpMessage, LpClientError> {
|
||||
fn to_lp_data(&self) -> Result<LpData, LpClientError> {
|
||||
let request_bytes = self.serialise().map_err(|e| {
|
||||
LpClientError::SendRegistrationRequest(format!("Failed to serialize request: {e}"))
|
||||
})?;
|
||||
@@ -31,14 +30,14 @@ impl LpDataSendExt for LpRegistrationRequest {
|
||||
request_bytes.len()
|
||||
);
|
||||
|
||||
Ok(LpMessage::new_registration(request_bytes))
|
||||
Ok(LpData::new_registration(request_bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl LpDataDeliverExt for LpRegistrationResponse {
|
||||
fn from_lp_data(data: LpMessage) -> Result<Self, LpClientError> {
|
||||
if data.kind() != LpMessageType::Registration {
|
||||
return Err(LpClientError::UnexpectedLpPayload { typ: data.kind() });
|
||||
fn from_lp_data(data: LpData) -> Result<Self, LpClientError> {
|
||||
if data.kind != LpDataKind::Registration {
|
||||
return Err(LpClientError::UnexpectedLpPayload { typ: data.kind });
|
||||
}
|
||||
|
||||
let response = LpRegistrationResponse::try_deserialise(&data.content)
|
||||
@@ -49,7 +48,7 @@ impl LpDataDeliverExt for LpRegistrationResponse {
|
||||
}
|
||||
|
||||
impl LpDataSendExt for ForwardPacketData {
|
||||
fn to_lp_data(&self) -> Result<LpMessage, LpClientError> {
|
||||
fn to_lp_data(&self) -> Result<LpData, LpClientError> {
|
||||
let request_bytes = self.to_bytes();
|
||||
|
||||
tracing::trace!(
|
||||
@@ -57,7 +56,7 @@ impl LpDataSendExt for ForwardPacketData {
|
||||
request_bytes.len()
|
||||
);
|
||||
|
||||
Ok(LpMessage::new_forward(request_bytes))
|
||||
Ok(LpData::new_forward(request_bytes))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,9 +70,9 @@ pub(crate) fn try_convert_forward_response(action: LpAction) -> Result<Vec<u8>,
|
||||
action => return Err(LpClientError::UnexpectedStateMachineAction { action }),
|
||||
};
|
||||
|
||||
if response_data.kind() != LpMessageType::Forward {
|
||||
if response_data.kind != LpDataKind::Forward {
|
||||
return Err(LpClientError::UnexpectedLpPayload {
|
||||
typ: response_data.kind(),
|
||||
typ: response_data.kind,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,10 @@ use crate::lp_client::state_machine_helpers::{extract_forwarded_response, prepar
|
||||
use nym_bandwidth_controller::{BandwidthTicketProvider, DEFAULT_TICKETS_TO_SPEND};
|
||||
use nym_credentials_interface::TicketType;
|
||||
use nym_crypto::asymmetric::{ed25519, x25519};
|
||||
use nym_lp::packet::EncryptedLpPacket;
|
||||
use nym_lp::packet::version;
|
||||
use nym_lp::packet::{EncryptedLpPacket, LpMessage};
|
||||
use nym_lp::peer::{DHKeyPair, LpLocalPeer, LpRemotePeer};
|
||||
use nym_lp::state_machine::LpStateMachine;
|
||||
use nym_lp::state_machine::{LpData, LpStateMachine};
|
||||
use nym_lp::transport::LpHandshakeChannel;
|
||||
use nym_lp::transport::traits::LpTransportChannel;
|
||||
use nym_lp::{Ciphersuite, KEM, LpSession};
|
||||
@@ -128,17 +128,14 @@ impl NestedLpSession {
|
||||
|
||||
/// Attempt to wrap the provided `LpData` into a `EncryptedLpPacket`
|
||||
/// using the inner state machine.
|
||||
fn prepare_transport_packet(&mut self, data: LpMessage) -> Result<EncryptedLpPacket> {
|
||||
fn prepare_transport_packet(&mut self, data: LpData) -> Result<EncryptedLpPacket> {
|
||||
let state_machine = self.state_machine_mut()?;
|
||||
prepare_send_packet(data, state_machine)
|
||||
}
|
||||
|
||||
/// Attempt to recover received `LpData` from the received `EncryptedLpPacket`
|
||||
/// using the inner state machine.
|
||||
fn extract_forwarded_response(
|
||||
&mut self,
|
||||
response_packet: EncryptedLpPacket,
|
||||
) -> Result<LpMessage> {
|
||||
fn extract_forwarded_response(&mut self, response_packet: EncryptedLpPacket) -> Result<LpData> {
|
||||
let state_machine = self.state_machine_mut()?;
|
||||
extract_forwarded_response(response_packet, state_machine)
|
||||
}
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::LpClientError;
|
||||
use nym_lp::packet::LpMessage;
|
||||
use nym_lp::state_machine::{LpAction, LpInput};
|
||||
use nym_lp::state_machine::{LpAction, LpData, LpInput};
|
||||
use nym_lp::{LpStateMachine, packet::EncryptedLpPacket};
|
||||
|
||||
/// Attempt to prepare the provided data for sending by wrapping it in appropriate `LpAction`,
|
||||
/// and attempting to extract `EncryptedLpPacket` from the provided state machine.
|
||||
pub(crate) fn prepare_send_packet(
|
||||
data: LpMessage,
|
||||
data: LpData,
|
||||
state_machine: &mut LpStateMachine,
|
||||
) -> Result<EncryptedLpPacket, LpClientError> {
|
||||
let action = state_machine
|
||||
@@ -27,7 +26,7 @@ pub(crate) fn prepare_send_packet(
|
||||
pub(crate) fn extract_forwarded_response(
|
||||
response_packet: EncryptedLpPacket,
|
||||
state_machine: &mut LpStateMachine,
|
||||
) -> Result<LpMessage, LpClientError> {
|
||||
) -> Result<LpData, LpClientError> {
|
||||
let action = state_machine
|
||||
.process_input(LpInput::ReceivePacket(response_packet))
|
||||
.ok_or(LpClientError::UnexpectedStateMachineHalt)??;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[package]
|
||||
name = "nym-network-requester"
|
||||
license = "GPL-3.0"
|
||||
version = "1.1.73"
|
||||
version = "1.1.72"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version = "1.85"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-cli"
|
||||
version = "1.1.72"
|
||||
version = "1.1.71"
|
||||
authors.workspace = true
|
||||
edition = "2021"
|
||||
license.workspace = true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nymvisor"
|
||||
version = "0.1.37"
|
||||
version = "0.1.36"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
+16
-32
@@ -1408,40 +1408,40 @@
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.22.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
|
||||
"integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "~1.20.3",
|
||||
"content-disposition": "~0.5.4",
|
||||
"body-parser": "1.20.3",
|
||||
"content-disposition": "0.5.4",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "~0.7.1",
|
||||
"cookie-signature": "~1.0.6",
|
||||
"cookie": "0.7.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "~1.3.1",
|
||||
"fresh": "~0.5.2",
|
||||
"http-errors": "~2.0.0",
|
||||
"finalhandler": "1.3.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "2.0.0",
|
||||
"merge-descriptors": "1.0.3",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.4.1",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "~0.1.12",
|
||||
"path-to-regexp": "0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "~6.14.0",
|
||||
"qs": "6.13.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.2.1",
|
||||
"send": "~0.19.0",
|
||||
"serve-static": "~1.16.2",
|
||||
"send": "0.19.0",
|
||||
"serve-static": "1.16.2",
|
||||
"setprototypeof": "1.2.0",
|
||||
"statuses": "~2.0.1",
|
||||
"statuses": "2.0.1",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
@@ -1461,22 +1461,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/express/node_modules/qs": {
|
||||
"version": "6.14.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz",
|
||||
"integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
|
||||
+111
-106
@@ -445,23 +445,23 @@ binary-extensions@^2.0.0:
|
||||
resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz"
|
||||
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||
|
||||
body-parser@~1.20.3:
|
||||
version "1.20.4"
|
||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.4.tgz#f8e20f4d06ca8a50a71ed329c15dccad1cdc547f"
|
||||
integrity sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==
|
||||
body-parser@1.20.3:
|
||||
version "1.20.3"
|
||||
resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz"
|
||||
integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==
|
||||
dependencies:
|
||||
bytes "~3.1.2"
|
||||
bytes "3.1.2"
|
||||
content-type "~1.0.5"
|
||||
debug "2.6.9"
|
||||
depd "2.0.0"
|
||||
destroy "~1.2.0"
|
||||
http-errors "~2.0.1"
|
||||
iconv-lite "~0.4.24"
|
||||
on-finished "~2.4.1"
|
||||
qs "~6.14.0"
|
||||
raw-body "~2.5.3"
|
||||
destroy "1.2.0"
|
||||
http-errors "2.0.0"
|
||||
iconv-lite "0.4.24"
|
||||
on-finished "2.4.1"
|
||||
qs "6.13.0"
|
||||
raw-body "2.5.2"
|
||||
type-is "~1.6.18"
|
||||
unpipe "~1.0.0"
|
||||
unpipe "1.0.0"
|
||||
|
||||
bonjour-service@^1.0.11:
|
||||
version "1.1.1"
|
||||
@@ -509,9 +509,9 @@ bytes@3.0.0:
|
||||
resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz"
|
||||
integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==
|
||||
|
||||
bytes@~3.1.2:
|
||||
bytes@3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
|
||||
resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz"
|
||||
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
|
||||
|
||||
call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
|
||||
@@ -609,9 +609,9 @@ connect-history-api-fallback@^2.0.0:
|
||||
resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz"
|
||||
integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==
|
||||
|
||||
content-disposition@~0.5.4:
|
||||
content-disposition@0.5.4:
|
||||
version "0.5.4"
|
||||
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
|
||||
resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz"
|
||||
integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
|
||||
dependencies:
|
||||
safe-buffer "5.2.1"
|
||||
@@ -621,15 +621,15 @@ content-type@~1.0.4, content-type@~1.0.5:
|
||||
resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz"
|
||||
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
|
||||
|
||||
cookie-signature@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454"
|
||||
integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==
|
||||
cookie-signature@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
|
||||
integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
|
||||
|
||||
cookie@~0.7.1:
|
||||
version "0.7.2"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7"
|
||||
integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==
|
||||
cookie@0.7.1:
|
||||
version "0.7.1"
|
||||
resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz"
|
||||
integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==
|
||||
|
||||
copy-webpack-plugin@^11.0.0:
|
||||
version "11.0.0"
|
||||
@@ -683,7 +683,7 @@ define-lazy-prop@^2.0.0:
|
||||
resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz"
|
||||
integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==
|
||||
|
||||
depd@2.0.0, depd@~2.0.0:
|
||||
depd@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz"
|
||||
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
|
||||
@@ -693,7 +693,7 @@ depd@~1.1.2:
|
||||
resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz"
|
||||
integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
|
||||
|
||||
destroy@1.2.0, destroy@~1.2.0:
|
||||
destroy@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz"
|
||||
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
|
||||
@@ -741,6 +741,11 @@ electron-to-chromium@^1.5.263:
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e"
|
||||
integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==
|
||||
|
||||
encodeurl@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz"
|
||||
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
|
||||
|
||||
encodeurl@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz"
|
||||
@@ -847,38 +852,38 @@ execa@^5.0.0:
|
||||
strip-final-newline "^2.0.0"
|
||||
|
||||
express@^4.17.3:
|
||||
version "4.22.1"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.22.1.tgz#1de23a09745a4fffdb39247b344bb5eaff382069"
|
||||
integrity sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==
|
||||
version "4.21.2"
|
||||
resolved "https://registry.npmjs.org/express/-/express-4.21.2.tgz"
|
||||
integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==
|
||||
dependencies:
|
||||
accepts "~1.3.8"
|
||||
array-flatten "1.1.1"
|
||||
body-parser "~1.20.3"
|
||||
content-disposition "~0.5.4"
|
||||
body-parser "1.20.3"
|
||||
content-disposition "0.5.4"
|
||||
content-type "~1.0.4"
|
||||
cookie "~0.7.1"
|
||||
cookie-signature "~1.0.6"
|
||||
cookie "0.7.1"
|
||||
cookie-signature "1.0.6"
|
||||
debug "2.6.9"
|
||||
depd "2.0.0"
|
||||
encodeurl "~2.0.0"
|
||||
escape-html "~1.0.3"
|
||||
etag "~1.8.1"
|
||||
finalhandler "~1.3.1"
|
||||
fresh "~0.5.2"
|
||||
http-errors "~2.0.0"
|
||||
finalhandler "1.3.1"
|
||||
fresh "0.5.2"
|
||||
http-errors "2.0.0"
|
||||
merge-descriptors "1.0.3"
|
||||
methods "~1.1.2"
|
||||
on-finished "~2.4.1"
|
||||
on-finished "2.4.1"
|
||||
parseurl "~1.3.3"
|
||||
path-to-regexp "~0.1.12"
|
||||
path-to-regexp "0.1.12"
|
||||
proxy-addr "~2.0.7"
|
||||
qs "~6.14.0"
|
||||
qs "6.13.0"
|
||||
range-parser "~1.2.1"
|
||||
safe-buffer "5.2.1"
|
||||
send "~0.19.0"
|
||||
serve-static "~1.16.2"
|
||||
send "0.19.0"
|
||||
serve-static "1.16.2"
|
||||
setprototypeof "1.2.0"
|
||||
statuses "~2.0.1"
|
||||
statuses "2.0.1"
|
||||
type-is "~1.6.18"
|
||||
utils-merge "1.0.1"
|
||||
vary "~1.1.2"
|
||||
@@ -925,17 +930,17 @@ fill-range@^7.0.1:
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
finalhandler@~1.3.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88"
|
||||
integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==
|
||||
finalhandler@1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz"
|
||||
integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==
|
||||
dependencies:
|
||||
debug "2.6.9"
|
||||
encodeurl "~2.0.0"
|
||||
escape-html "~1.0.3"
|
||||
on-finished "~2.4.1"
|
||||
on-finished "2.4.1"
|
||||
parseurl "~1.3.3"
|
||||
statuses "~2.0.2"
|
||||
statuses "2.0.1"
|
||||
unpipe "~1.0.0"
|
||||
|
||||
find-up@^4.0.0:
|
||||
@@ -956,9 +961,9 @@ forwarded@0.2.0:
|
||||
resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz"
|
||||
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
|
||||
|
||||
fresh@~0.5.2:
|
||||
fresh@0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||
resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz"
|
||||
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
|
||||
|
||||
fs-monkey@^1.0.3:
|
||||
@@ -1116,6 +1121,17 @@ http-deceiver@^1.2.7:
|
||||
resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz"
|
||||
integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==
|
||||
|
||||
http-errors@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz"
|
||||
integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
|
||||
dependencies:
|
||||
depd "2.0.0"
|
||||
inherits "2.0.4"
|
||||
setprototypeof "1.2.0"
|
||||
statuses "2.0.1"
|
||||
toidentifier "1.0.1"
|
||||
|
||||
http-errors@~1.6.2:
|
||||
version "1.6.3"
|
||||
resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz"
|
||||
@@ -1126,17 +1142,6 @@ http-errors@~1.6.2:
|
||||
setprototypeof "1.1.0"
|
||||
statuses ">= 1.4.0 < 2"
|
||||
|
||||
http-errors@~2.0.0, http-errors@~2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b"
|
||||
integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==
|
||||
dependencies:
|
||||
depd "~2.0.0"
|
||||
inherits "~2.0.4"
|
||||
setprototypeof "~1.2.0"
|
||||
statuses "~2.0.2"
|
||||
toidentifier "~1.0.1"
|
||||
|
||||
http-parser-js@>=0.5.1:
|
||||
version "0.5.8"
|
||||
resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz"
|
||||
@@ -1167,9 +1172,9 @@ human-signals@^2.1.0:
|
||||
resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz"
|
||||
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
|
||||
|
||||
iconv-lite@~0.4.24:
|
||||
iconv-lite@0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
@@ -1195,7 +1200,7 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4:
|
||||
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
@@ -1483,9 +1488,9 @@ obuf@^1.0.0, obuf@^1.1.2:
|
||||
resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz"
|
||||
integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
|
||||
|
||||
on-finished@~2.4.1:
|
||||
on-finished@2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
|
||||
resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz"
|
||||
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
|
||||
dependencies:
|
||||
ee-first "1.1.1"
|
||||
@@ -1570,9 +1575,9 @@ path-parse@^1.0.7:
|
||||
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
path-to-regexp@~0.1.12:
|
||||
path-to-regexp@0.1.12:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7"
|
||||
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz"
|
||||
integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==
|
||||
|
||||
path-type@^4.0.0:
|
||||
@@ -1615,12 +1620,12 @@ punycode@^2.1.0:
|
||||
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz"
|
||||
integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
|
||||
|
||||
qs@~6.14.0:
|
||||
version "6.14.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.2.tgz#b5634cf9d9ad9898e31fba3504e866e8efb6798c"
|
||||
integrity sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==
|
||||
qs@6.13.0:
|
||||
version "6.13.0"
|
||||
resolved "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz"
|
||||
integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==
|
||||
dependencies:
|
||||
side-channel "^1.1.0"
|
||||
side-channel "^1.0.6"
|
||||
|
||||
queue-microtask@^1.2.2:
|
||||
version "1.2.3"
|
||||
@@ -1639,15 +1644,15 @@ range-parser@^1.2.1, range-parser@~1.2.1:
|
||||
resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz"
|
||||
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
|
||||
|
||||
raw-body@~2.5.3:
|
||||
version "2.5.3"
|
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2"
|
||||
integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==
|
||||
raw-body@2.5.2:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz"
|
||||
integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==
|
||||
dependencies:
|
||||
bytes "~3.1.2"
|
||||
http-errors "~2.0.1"
|
||||
iconv-lite "~0.4.24"
|
||||
unpipe "~1.0.0"
|
||||
bytes "3.1.2"
|
||||
http-errors "2.0.0"
|
||||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
readable-stream@^2.0.1:
|
||||
version "2.3.8"
|
||||
@@ -1777,24 +1782,24 @@ selfsigned@^2.1.1:
|
||||
dependencies:
|
||||
node-forge "^1"
|
||||
|
||||
send@~0.19.0, send@~0.19.1:
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29"
|
||||
integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==
|
||||
send@0.19.0:
|
||||
version "0.19.0"
|
||||
resolved "https://registry.npmjs.org/send/-/send-0.19.0.tgz"
|
||||
integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==
|
||||
dependencies:
|
||||
debug "2.6.9"
|
||||
depd "2.0.0"
|
||||
destroy "1.2.0"
|
||||
encodeurl "~2.0.0"
|
||||
encodeurl "~1.0.2"
|
||||
escape-html "~1.0.3"
|
||||
etag "~1.8.1"
|
||||
fresh "~0.5.2"
|
||||
http-errors "~2.0.1"
|
||||
fresh "0.5.2"
|
||||
http-errors "2.0.0"
|
||||
mime "1.6.0"
|
||||
ms "2.1.3"
|
||||
on-finished "~2.4.1"
|
||||
on-finished "2.4.1"
|
||||
range-parser "~1.2.1"
|
||||
statuses "~2.0.2"
|
||||
statuses "2.0.1"
|
||||
|
||||
serialize-javascript@^6.0.0, serialize-javascript@^6.0.2:
|
||||
version "6.0.2"
|
||||
@@ -1816,22 +1821,22 @@ serve-index@^1.9.1:
|
||||
mime-types "~2.1.17"
|
||||
parseurl "~1.3.2"
|
||||
|
||||
serve-static@~1.16.2:
|
||||
version "1.16.3"
|
||||
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9"
|
||||
integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==
|
||||
serve-static@1.16.2:
|
||||
version "1.16.2"
|
||||
resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz"
|
||||
integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==
|
||||
dependencies:
|
||||
encodeurl "~2.0.0"
|
||||
escape-html "~1.0.3"
|
||||
parseurl "~1.3.3"
|
||||
send "~0.19.1"
|
||||
send "0.19.0"
|
||||
|
||||
setprototypeof@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz"
|
||||
integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
|
||||
|
||||
setprototypeof@1.2.0, setprototypeof@~1.2.0:
|
||||
setprototypeof@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz"
|
||||
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
|
||||
@@ -1889,9 +1894,9 @@ side-channel-weakmap@^1.0.2:
|
||||
object-inspect "^1.13.3"
|
||||
side-channel-map "^1.0.1"
|
||||
|
||||
side-channel@^1.1.0:
|
||||
side-channel@^1.0.6:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9"
|
||||
resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz"
|
||||
integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
@@ -1955,16 +1960,16 @@ spdy@^4.0.2:
|
||||
select-hose "^2.0.0"
|
||||
spdy-transport "^3.0.0"
|
||||
|
||||
statuses@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz"
|
||||
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
|
||||
|
||||
"statuses@>= 1.4.0 < 2":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz"
|
||||
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
|
||||
|
||||
statuses@~2.0.1, statuses@~2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382"
|
||||
integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==
|
||||
|
||||
string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
|
||||
@@ -2034,9 +2039,9 @@ to-regex-range@^5.0.1:
|
||||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
toidentifier@~1.0.1:
|
||||
toidentifier@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
||||
resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz"
|
||||
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
||||
|
||||
type-is@~1.6.18:
|
||||
@@ -2047,7 +2052,7 @@ type-is@~1.6.18:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.24"
|
||||
|
||||
unpipe@~1.0.0:
|
||||
unpipe@1.0.0, unpipe@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
|
||||
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
|
||||
|
||||
Reference in New Issue
Block a user