More work on the reciever end, and outfox format
This commit is contained in:
@@ -53,7 +53,7 @@ where
|
||||
}
|
||||
|
||||
async fn on_messages(&mut self, mut mix_packets: Vec<MixPacket>) {
|
||||
debug_assert!(!mix_packets.is_empty());
|
||||
assert!(!mix_packets.is_empty());
|
||||
|
||||
let result = if mix_packets.len() == 1 {
|
||||
let mix_packet = mix_packets.pop().unwrap();
|
||||
@@ -103,7 +103,7 @@ where
|
||||
}
|
||||
}
|
||||
shutdown.recv_timeout().await;
|
||||
log::debug!("MixTrafficController: Exiting");
|
||||
log::error!("MixTrafficController: Exiting");
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -71,7 +71,8 @@ impl AcknowledgementListener {
|
||||
while !shutdown.is_shutdown() {
|
||||
tokio::select! {
|
||||
acks = self.ack_receiver.next() => match acks {
|
||||
Some(acks) => self.handle_ack_receiver_item(acks).await,
|
||||
|
||||
Some(acks) => {self.handle_ack_receiver_item(acks).await}
|
||||
None => {
|
||||
log::trace!("AcknowledgementListener: Stopping since channel closed");
|
||||
break;
|
||||
|
||||
+2
-2
@@ -49,11 +49,11 @@ where
|
||||
packet_recipient: Recipient,
|
||||
chunk_data: Fragment,
|
||||
) -> Result<PreparedFragment, PreparationError> {
|
||||
info!("retransmitting normal packet...");
|
||||
debug!("retransmitting normal packet...");
|
||||
|
||||
// TODO: Figure out retransmission packet type signaling
|
||||
self.message_handler
|
||||
.try_prepare_single_chunk_for_sending(packet_recipient, chunk_data, PacketType::Mix)
|
||||
.try_prepare_single_chunk_for_sending(packet_recipient, chunk_data, PacketType::Outfox)
|
||||
.await
|
||||
}
|
||||
|
||||
|
||||
@@ -431,7 +431,7 @@ where
|
||||
lane: TransmissionLane,
|
||||
packet_type: PacketType,
|
||||
) -> Result<(), PreparationError> {
|
||||
info!("Sending non-reply message with packet type {packet_type}");
|
||||
debug!("Sending non-reply message with packet type {packet_type}");
|
||||
// TODO: I really dislike existence of this assertion, it implies code has to be re-organised
|
||||
debug_assert!(!matches!(message, NymMessage::Reply(_)));
|
||||
|
||||
@@ -439,7 +439,11 @@ where
|
||||
let topology_permit = self.topology_access.get_read_permit().await;
|
||||
let topology = self.get_topology(&topology_permit)?;
|
||||
|
||||
let packet_size = self.optimal_packet_size(&message);
|
||||
let packet_size = if packet_type == PacketType::Outfox {
|
||||
PacketSize::OutfoxRegularPacket
|
||||
} else {
|
||||
self.optimal_packet_size(&message)
|
||||
};
|
||||
debug!("Using {packet_size} packets for {message}");
|
||||
let fragments = self
|
||||
.message_preparer
|
||||
@@ -482,7 +486,7 @@ where
|
||||
amount: u32,
|
||||
packet_type: PacketType,
|
||||
) -> Result<(), PreparationError> {
|
||||
info!("Sending additional reply SURBs with packet type {packet_type}");
|
||||
debug!("Sending additional reply SURBs with packet type {packet_type}");
|
||||
let sender_tag = self.get_or_create_sender_tag(&recipient);
|
||||
let (reply_surbs, reply_keys) =
|
||||
self.generate_reply_surbs_with_keys(amount as usize).await?;
|
||||
@@ -514,7 +518,7 @@ where
|
||||
lane: TransmissionLane,
|
||||
packet_type: PacketType,
|
||||
) -> Result<(), SurbWrappedPreparationError> {
|
||||
info!("Sending message with reply SURBs with packet type {packet_type}");
|
||||
debug!("Sending message with reply SURBs with packet type {packet_type}");
|
||||
let sender_tag = self.get_or_create_sender_tag(&recipient);
|
||||
let (reply_surbs, reply_keys) = self
|
||||
.generate_reply_surbs_with_keys(num_reply_surbs as usize)
|
||||
@@ -538,7 +542,7 @@ where
|
||||
chunk: Fragment,
|
||||
packet_type: PacketType,
|
||||
) -> Result<PreparedFragment, PreparationError> {
|
||||
info!("Sending single chunk with packet type {packet_type}");
|
||||
debug!("Sending single chunk with packet type {packet_type}");
|
||||
let topology_permit = self.topology_access.get_read_permit().await;
|
||||
let topology = self.get_topology(&topology_permit)?;
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
|
||||
};
|
||||
|
||||
if let Some(completed) = completed_message {
|
||||
info!("received {completed}");
|
||||
debug!("received {completed}");
|
||||
completed_messages.push(completed)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,6 +579,8 @@ impl<C, St> GatewayClient<C, St> {
|
||||
&mut self,
|
||||
packets: Vec<MixPacket>,
|
||||
) -> Result<(), GatewayClientError> {
|
||||
warn!("Sending {} mix packets", packets.len());
|
||||
|
||||
if !self.authenticated {
|
||||
return Err(GatewayClientError::NotAuthenticated);
|
||||
}
|
||||
@@ -623,9 +625,10 @@ impl<C, St> GatewayClient<C, St> {
|
||||
) -> Result<(), GatewayClientError> {
|
||||
if let Err(err) = self.send_websocket_message_without_response(msg).await {
|
||||
if err.is_closed_connection() && self.should_reconnect_on_failure {
|
||||
info!("Going to attempt a reconnection");
|
||||
error!("Going to attempt a reconnection");
|
||||
self.attempt_reconnection().await
|
||||
} else {
|
||||
error!("{err}");
|
||||
Err(err)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -50,10 +50,15 @@ impl PacketRouter {
|
||||
let ack_overhead = PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN;
|
||||
|
||||
for received_packet in unwrapped_packets {
|
||||
if received_packet.len() == PacketSize::AckPacket.plaintext_size() {
|
||||
if received_packet.len() == PacketSize::AckPacket.plaintext_size()
|
||||
|| received_packet.len() == PacketSize::OutfoxAckPacket.plaintext_size()
|
||||
{
|
||||
received_acks.push(received_packet);
|
||||
} else if received_packet.len()
|
||||
== PacketSize::RegularPacket.plaintext_size() - ack_overhead
|
||||
|| received_packet.len()
|
||||
== PacketSize::OutfoxRegularPacket.plaintext_size() - ack_overhead
|
||||
|| received_packet.len() == PacketSize::OutfoxRegularPacket.size() - 6
|
||||
{
|
||||
trace!("routing regular packet");
|
||||
received_messages.push(received_packet);
|
||||
|
||||
@@ -10,7 +10,7 @@ use nym_sphinx_forwarding::packet::MixPacket;
|
||||
use nym_sphinx_framing::packet::FramedNymPacket;
|
||||
use nym_sphinx_params::{PacketSize, PacketType};
|
||||
use nym_sphinx_types::{
|
||||
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, NymPacket, Payload,
|
||||
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, NymPacket, NymProcessedPacket,
|
||||
PrivateKey, ProcessedPacket,
|
||||
};
|
||||
use std::convert::TryFrom;
|
||||
@@ -56,10 +56,10 @@ impl SphinxPacketProcessor {
|
||||
fn perform_initial_packet_processing(
|
||||
&self,
|
||||
packet: NymPacket,
|
||||
) -> Result<ProcessedPacket, MixProcessingError> {
|
||||
) -> Result<NymProcessedPacket, MixProcessingError> {
|
||||
measure!({
|
||||
packet.process(&self.sphinx_key).map_err(|err| {
|
||||
debug!("Failed to unwrap Sphinx packet: {err}");
|
||||
info!("Failed to unwrap NymPacket packet: {err}");
|
||||
MixProcessingError::NymPacketProcessingError(err)
|
||||
})
|
||||
})
|
||||
@@ -73,7 +73,7 @@ impl SphinxPacketProcessor {
|
||||
fn perform_initial_unwrapping(
|
||||
&self,
|
||||
received: FramedNymPacket,
|
||||
) -> Result<ProcessedPacket, MixProcessingError> {
|
||||
) -> Result<NymProcessedPacket, MixProcessingError> {
|
||||
measure!({
|
||||
let packet = received.into_inner();
|
||||
|
||||
@@ -101,14 +101,17 @@ impl SphinxPacketProcessor {
|
||||
fn split_hop_data_into_ack_and_message(
|
||||
&self,
|
||||
mut extracted_data: Vec<u8>,
|
||||
packet_type: PacketType,
|
||||
) -> Result<(Vec<u8>, Vec<u8>), MixProcessingError> {
|
||||
let ack_len = SurbAck::len(Some(packet_type));
|
||||
|
||||
// in theory it's impossible for this to fail since it managed to go into correct `match`
|
||||
// branch at the caller
|
||||
if extracted_data.len() < SurbAck::len() {
|
||||
if extracted_data.len() < ack_len {
|
||||
return Err(MixProcessingError::NoSurbAckInFinalHop);
|
||||
}
|
||||
|
||||
let message = extracted_data.split_off(SurbAck::len());
|
||||
let message = extracted_data.split_off(ack_len);
|
||||
let ack_data = extracted_data;
|
||||
Ok((ack_data, message))
|
||||
}
|
||||
@@ -130,13 +133,18 @@ impl SphinxPacketProcessor {
|
||||
| PacketSize::ExtendedPacket8
|
||||
| PacketSize::ExtendedPacket16
|
||||
| PacketSize::ExtendedPacket32
|
||||
| PacketSize::OutfoxRegularPacket
|
||||
| PacketSize::OutfoxExtendedPacket8
|
||||
| PacketSize::OutfoxExtendedPacket16
|
||||
| PacketSize::OutfoxExtendedPacket32 => {
|
||||
| PacketSize::OutfoxRegularPacket => {
|
||||
trace!("received a normal packet!");
|
||||
let (ack_data, message) = self.split_hop_data_into_ack_and_message(data)?;
|
||||
let (ack_first_hop, ack_packet) = SurbAck::try_recover_first_hop_packet(&ack_data)?;
|
||||
let (ack_data, message) =
|
||||
self.split_hop_data_into_ack_and_message(data, packet_type)?;
|
||||
let (ack_first_hop, ack_packet) =
|
||||
match SurbAck::try_recover_first_hop_packet(&ack_data, packet_type) {
|
||||
Ok((first_hop, packet)) => (first_hop, packet),
|
||||
Err(err) => {
|
||||
error!("Failed to recover first hop from ack data: {err}");
|
||||
return Err(err.into());
|
||||
}
|
||||
};
|
||||
let forward_ack = MixPacket::new(ack_first_hop, ack_packet, packet_type);
|
||||
Ok((Some(forward_ack), message))
|
||||
}
|
||||
@@ -149,14 +157,12 @@ impl SphinxPacketProcessor {
|
||||
fn process_final_hop(
|
||||
&self,
|
||||
destination: DestinationAddressBytes,
|
||||
payload: Payload,
|
||||
payload: Vec<u8>,
|
||||
packet_size: PacketSize,
|
||||
packet_type: PacketType,
|
||||
) -> Result<MixProcessingResult, MixProcessingError> {
|
||||
let packet_message = payload.recover_plaintext()?;
|
||||
|
||||
let (forward_ack, message) =
|
||||
self.split_into_ack_and_message(packet_message, packet_size, packet_type)?;
|
||||
self.split_into_ack_and_message(payload, packet_size, packet_type)?;
|
||||
|
||||
Ok(MixProcessingResult::FinalHop(ProcessedFinalHop {
|
||||
destination,
|
||||
@@ -169,18 +175,48 @@ impl SphinxPacketProcessor {
|
||||
/// or a final hop.
|
||||
fn perform_final_processing(
|
||||
&self,
|
||||
packet: ProcessedPacket,
|
||||
packet: NymProcessedPacket,
|
||||
packet_size: PacketSize,
|
||||
packet_type: PacketType,
|
||||
) -> Result<MixProcessingResult, MixProcessingError> {
|
||||
match packet {
|
||||
ProcessedPacket::ForwardHop(packet, address, delay) => {
|
||||
self.process_forward_hop(NymPacket::Sphinx(*packet), address, delay, packet_type)
|
||||
NymProcessedPacket::Sphinx(packet) => {
|
||||
match packet {
|
||||
ProcessedPacket::ForwardHop(packet, address, delay) => self
|
||||
.process_forward_hop(
|
||||
NymPacket::Sphinx(*packet),
|
||||
address,
|
||||
delay,
|
||||
packet_type,
|
||||
),
|
||||
// right now there's no use for the surb_id included in the header - probably it should get removed from the
|
||||
// sphinx all together?
|
||||
ProcessedPacket::FinalHop(destination, _, payload) => self.process_final_hop(
|
||||
destination,
|
||||
payload.recover_plaintext()?,
|
||||
packet_size,
|
||||
packet_type,
|
||||
),
|
||||
}
|
||||
}
|
||||
// right now there's no use for the surb_id included in the header - probably it should get removed from the
|
||||
// sphinx all together?
|
||||
ProcessedPacket::FinalHop(destination, _, payload) => {
|
||||
self.process_final_hop(destination, payload, packet_size, packet_type)
|
||||
NymProcessedPacket::Outfox(packet) => {
|
||||
let next_address = *packet.next_address();
|
||||
let packet = packet.into_packet();
|
||||
if packet.is_final_hop() {
|
||||
self.process_final_hop(
|
||||
DestinationAddressBytes::from_bytes(next_address),
|
||||
packet.recover_plaintext().to_vec(),
|
||||
packet_size,
|
||||
packet_type,
|
||||
)
|
||||
} else {
|
||||
let mix_packet = MixPacket::new(
|
||||
NymNodeRoutingAddress::try_from_bytes(&next_address)?,
|
||||
NymPacket::Outfox(packet),
|
||||
PacketType::Outfox,
|
||||
);
|
||||
Ok(MixProcessingResult::ForwardHop(mix_packet, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,31 +261,71 @@ mod tests {
|
||||
|
||||
let short_data = vec![42u8];
|
||||
assert!(processor
|
||||
.split_hop_data_into_ack_and_message(short_data)
|
||||
.split_hop_data_into_ack_and_message(short_data, PacketType::Mix)
|
||||
.is_err());
|
||||
|
||||
let sufficient_data = vec![42u8; SurbAck::len()];
|
||||
let sufficient_data = vec![42u8; SurbAck::len(Some(PacketType::Mix))];
|
||||
let (ack, data) = processor
|
||||
.split_hop_data_into_ack_and_message(sufficient_data.clone())
|
||||
.split_hop_data_into_ack_and_message(sufficient_data.clone(), PacketType::Mix)
|
||||
.unwrap();
|
||||
assert_eq!(sufficient_data, ack);
|
||||
assert!(data.is_empty());
|
||||
|
||||
let long_data = vec![42u8; SurbAck::len() * 5];
|
||||
let long_data = vec![42u8; SurbAck::len(Some(PacketType::Mix)) * 5];
|
||||
let (ack, data) = processor
|
||||
.split_hop_data_into_ack_and_message(long_data)
|
||||
.split_hop_data_into_ack_and_message(long_data, PacketType::Mix)
|
||||
.unwrap();
|
||||
assert_eq!(ack.len(), SurbAck::len());
|
||||
assert_eq!(data.len(), SurbAck::len() * 4)
|
||||
assert_eq!(ack.len(), SurbAck::len(Some(PacketType::Mix)));
|
||||
assert_eq!(data.len(), SurbAck::len(Some(PacketType::Mix)) * 4)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn splitting_hop_data_works_for_sufficiently_long_payload_outfox() {
|
||||
let processor = fixture();
|
||||
|
||||
let short_data = vec![42u8];
|
||||
assert!(processor
|
||||
.split_hop_data_into_ack_and_message(short_data, PacketType::Outfox)
|
||||
.is_err());
|
||||
|
||||
let sufficient_data = vec![42u8; SurbAck::len(Some(PacketType::Outfox))];
|
||||
let (ack, data) = processor
|
||||
.split_hop_data_into_ack_and_message(sufficient_data.clone(), PacketType::Outfox)
|
||||
.unwrap();
|
||||
assert_eq!(sufficient_data, ack);
|
||||
assert!(data.is_empty());
|
||||
|
||||
let long_data = vec![42u8; SurbAck::len(Some(PacketType::Outfox)) * 5];
|
||||
let (ack, data) = processor
|
||||
.split_hop_data_into_ack_and_message(long_data, PacketType::Outfox)
|
||||
.unwrap();
|
||||
assert_eq!(ack.len(), SurbAck::len(Some(PacketType::Outfox)));
|
||||
assert_eq!(data.len(), SurbAck::len(Some(PacketType::Outfox)) * 4)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn splitting_into_ack_and_message_returns_whole_data_for_ack() {
|
||||
let processor = fixture();
|
||||
|
||||
let data = vec![42u8; SurbAck::len() + 10];
|
||||
let data = vec![42u8; SurbAck::len(Some(PacketType::Mix)) + 10];
|
||||
let (ack, message) = processor
|
||||
.split_into_ack_and_message(data.clone(), PacketSize::AckPacket, Default::default())
|
||||
.split_into_ack_and_message(data.clone(), PacketSize::AckPacket, PacketType::Mix)
|
||||
.unwrap();
|
||||
assert!(ack.is_none());
|
||||
assert_eq!(data, message)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn splitting_into_ack_and_message_returns_whole_data_for_ack_outfox() {
|
||||
let processor = fixture();
|
||||
|
||||
let data = vec![42u8; SurbAck::len(Some(PacketType::Outfox)) + 10];
|
||||
let (ack, message) = processor
|
||||
.split_into_ack_and_message(
|
||||
data.clone(),
|
||||
PacketSize::OutfoxAckPacket,
|
||||
PacketType::Outfox,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(ack.is_none());
|
||||
assert_eq!(data, message)
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
|
||||
use crate::AckKey;
|
||||
use nym_crypto::symmetric::stream_cipher::{self, encrypt, iv_from_slice, random_iv, IvSizeUser};
|
||||
use nym_sphinx_params::{
|
||||
packet_sizes::PacketSize, AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN,
|
||||
};
|
||||
use nym_sphinx_params::{AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
// TODO: should those functions even exist in this file?
|
||||
@@ -28,9 +26,9 @@ pub fn recover_identifier(
|
||||
) -> Option<SerializedFragmentIdentifier> {
|
||||
// The content of an 'ACK' packet consists of AckEncryptionAlgorithm::IV followed by
|
||||
// serialized FragmentIdentifier
|
||||
if iv_id_ciphertext.len() != PacketSize::AckPacket.plaintext_size() {
|
||||
return None;
|
||||
}
|
||||
// if iv_id_ciphertext.len() != PacketSize::AckPacket.plaintext_size() {
|
||||
// return None;
|
||||
// }
|
||||
|
||||
let iv_size = AckEncryptionAlgorithm::iv_size();
|
||||
let iv = iv_from_slice::<AckEncryptionAlgorithm>(&iv_id_ciphertext[..iv_size]);
|
||||
|
||||
@@ -17,6 +17,7 @@ use std::convert::TryFrom;
|
||||
use std::time;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SurbAck {
|
||||
surb_ack_packet: NymPacket,
|
||||
first_hop_address: NymNodeRoutingAddress,
|
||||
@@ -55,15 +56,24 @@ impl SurbAck {
|
||||
|
||||
let surb_ack_payload = prepare_identifier(rng, ack_key, marshaled_fragment_id);
|
||||
let packet_size = match packet_type {
|
||||
PacketType::Outfox => PacketSize::OutfoxAckPacket.payload_size(),
|
||||
PacketType::Outfox => {
|
||||
if surb_ack_payload.len() >= 48 {
|
||||
surb_ack_payload.len()
|
||||
} else {
|
||||
48
|
||||
}
|
||||
}
|
||||
PacketType::Mix => PacketSize::AckPacket.payload_size(),
|
||||
PacketType::Vpn => PacketSize::AckPacket.payload_size(),
|
||||
};
|
||||
|
||||
let surb_ack_packet = match packet_type {
|
||||
PacketType::Outfox => {
|
||||
NymPacket::outfox_build(surb_ack_payload, route.as_slice(), Some(packet_size))?
|
||||
}
|
||||
PacketType::Outfox => NymPacket::outfox_build(
|
||||
surb_ack_payload,
|
||||
route.as_slice(),
|
||||
&destination,
|
||||
Some(packet_size),
|
||||
)?,
|
||||
PacketType::Mix => NymPacket::sphinx_build(
|
||||
packet_size,
|
||||
surb_ack_payload,
|
||||
@@ -92,10 +102,17 @@ impl SurbAck {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn len() -> usize {
|
||||
pub fn len(packet_type: Option<PacketType>) -> usize {
|
||||
// TODO: this will be variable once/if we decide to introduce optimization described
|
||||
// in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size()
|
||||
PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN
|
||||
let packet_type = packet_type.unwrap_or(PacketType::Mix);
|
||||
match packet_type {
|
||||
PacketType::Outfox => {
|
||||
PacketSize::OutfoxAckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN
|
||||
}
|
||||
PacketType::Mix => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN,
|
||||
PacketType::Vpn => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expected_total_delay(&self) -> Delay {
|
||||
@@ -116,21 +133,19 @@ impl SurbAck {
|
||||
// partial reciprocal of `prepare_for_sending` performed by the gateway
|
||||
pub fn try_recover_first_hop_packet(
|
||||
b: &[u8],
|
||||
packet_type: PacketType,
|
||||
) -> Result<(NymNodeRoutingAddress, NymPacket), SurbAckRecoveryError> {
|
||||
if b.len() != Self::len() {
|
||||
Err(SurbAckRecoveryError::InvalidPacketSize {
|
||||
received: b.len(),
|
||||
expected: Self::len(),
|
||||
})
|
||||
} else {
|
||||
let address = NymNodeRoutingAddress::try_from_bytes(b)?;
|
||||
let address = NymNodeRoutingAddress::try_from_bytes(b)?;
|
||||
|
||||
// TODO: this will be variable once/if we decide to introduce optimization described
|
||||
// in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size()
|
||||
let address_offset = MAX_NODE_ADDRESS_UNPADDED_LEN;
|
||||
let packet = NymPacket::sphinx_from_bytes(&b[address_offset..])?;
|
||||
// TODO: this will be variable once/if we decide to introduce optimization described
|
||||
// in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size()
|
||||
let address_offset = MAX_NODE_ADDRESS_UNPADDED_LEN;
|
||||
let packet = match packet_type {
|
||||
PacketType::Outfox => NymPacket::outfox_from_bytes(&b[address_offset..])?,
|
||||
PacketType::Mix => NymPacket::sphinx_from_bytes(&b[address_offset..])?,
|
||||
PacketType::Vpn => NymPacket::sphinx_from_bytes(&b[address_offset..])?,
|
||||
};
|
||||
|
||||
Ok((address, packet))
|
||||
}
|
||||
Ok((address, packet))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ impl Encoder<FramedNymPacket> for NymCodec {
|
||||
fn encode(&mut self, item: FramedNymPacket, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
item.header.encode(dst);
|
||||
let packet_bytes = item.packet.to_bytes()?;
|
||||
dst.put(packet_bytes.as_slice());
|
||||
let encoded = packet_bytes.as_slice();
|
||||
dst.put(encoded);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -103,22 +104,23 @@ impl Decoder for NymCodec {
|
||||
// reserve for that.
|
||||
// we also assume the next packet coming from the same client will use exactly the same versioning
|
||||
// as the current packet
|
||||
let mut allocate_for_next_packet = header.size() + PacketSize::AckPacket.size();
|
||||
if !src.is_empty() {
|
||||
match Header::decode(src) {
|
||||
Ok(Some(next_header)) => {
|
||||
allocate_for_next_packet = next_header.size() + next_header.packet_size.size();
|
||||
}
|
||||
Ok(None) => {
|
||||
// we don't have enough information to know how much to reserve, fallback to the ack case
|
||||
}
|
||||
|
||||
// the next frame will be malformed but let's leave handling the error to the next
|
||||
// call to 'decode', as presumably, the current sphinx packet is still valid
|
||||
Err(_) => return Ok(Some(nymsphinx_packet)),
|
||||
};
|
||||
}
|
||||
src.reserve(allocate_for_next_packet);
|
||||
// let mut allocate_for_next_packet = header.size() + PacketSize::AckPacket.size();
|
||||
// if !src.is_empty() {
|
||||
// match Header::decode(src) {
|
||||
// Ok(Some(next_header)) => {
|
||||
// allocate_for_next_packet = next_header.size() + next_header.packet_size.size();
|
||||
// }
|
||||
// Ok(None) => {
|
||||
// // we don't have enough information to know how much to reserve, fallback to the ack case
|
||||
// }
|
||||
|
||||
// // the next frame will be malformed but let's leave handling the error to the next
|
||||
// // call to 'decode', as presumably, the current sphinx packet is still valid
|
||||
// Err(_) => return Ok(Some(nymsphinx_packet)),
|
||||
// };
|
||||
// }
|
||||
// src.reserve(allocate_for_next_packet);
|
||||
Ok(Some(nymsphinx_packet))
|
||||
}
|
||||
}
|
||||
@@ -154,11 +156,16 @@ mod packet_encoding {
|
||||
node4_pk,
|
||||
);
|
||||
|
||||
let destination = Destination::new(
|
||||
DestinationAddressBytes::from_bytes([3u8; DESTINATION_ADDRESS_LENGTH]),
|
||||
[4u8; IDENTIFIER_LENGTH],
|
||||
);
|
||||
|
||||
let route = &[node1, node2, node3, node4];
|
||||
|
||||
let payload = vec![1; 48];
|
||||
|
||||
NymPacket::outfox_build(payload, route, Some(size.plaintext_size())).unwrap()
|
||||
NymPacket::outfox_build(payload, route, &destination, Some(size.plaintext_size())).unwrap()
|
||||
}
|
||||
|
||||
fn make_valid_sphinx_packet(size: PacketSize) -> NymPacket {
|
||||
|
||||
@@ -24,14 +24,19 @@ impl FramedNymPacket {
|
||||
// already managed to somehow create a sphinx packet
|
||||
let packet_size = PacketSize::get_type(packet.len()).unwrap();
|
||||
|
||||
FramedNymPacket {
|
||||
header: Header {
|
||||
packet_version: PacketVersion::new(use_legacy_version),
|
||||
packet_size,
|
||||
packet_type,
|
||||
},
|
||||
packet,
|
||||
}
|
||||
let use_legacy = if packet_type == PacketType::Outfox {
|
||||
false
|
||||
} else {
|
||||
use_legacy_version
|
||||
};
|
||||
|
||||
let header = Header {
|
||||
packet_version: PacketVersion::new(use_legacy),
|
||||
packet_size,
|
||||
packet_type,
|
||||
};
|
||||
|
||||
FramedNymPacket { header, packet }
|
||||
}
|
||||
|
||||
pub fn header(&self) -> Header {
|
||||
@@ -96,16 +101,16 @@ impl Header {
|
||||
|
||||
pub(crate) fn encode(&self, dst: &mut BytesMut) {
|
||||
// we reserve one byte for `packet_size` and the other for `mode`
|
||||
dst.reserve(Self::LEGACY_SIZE);
|
||||
// dst.reserve(Self::LEGACY_SIZE);
|
||||
if let Some(version) = self.packet_version.as_u8() {
|
||||
dst.reserve(Self::VERSIONED_SIZE);
|
||||
// dst.reserve(Self::VERSIONED_SIZE);
|
||||
dst.put_u8(version)
|
||||
}
|
||||
|
||||
dst.put_u8(self.packet_size as u8);
|
||||
dst.put_u8(self.packet_type as u8);
|
||||
// reserve bytes for the actual packet
|
||||
dst.reserve(self.packet_size.size());
|
||||
// dst.reserve(self.packet_size.size());
|
||||
}
|
||||
|
||||
pub(crate) fn decode(src: &mut BytesMut) -> Result<Option<Self>, NymCodecError> {
|
||||
|
||||
@@ -28,11 +28,9 @@ const EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + SPHINX_PACKET_OVERHEAD;
|
||||
const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + SPHINX_PACKET_OVERHEAD;
|
||||
const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + SPHINX_PACKET_OVERHEAD;
|
||||
|
||||
const OUTFOX_ACK_PACKET_SIZE: usize = ACK_IV_SIZE + FRAG_ID_LEN + OUTFOX_PACKET_OVERHEAD;
|
||||
// 48 is min outfox payload size
|
||||
const OUTFOX_ACK_PACKET_SIZE: usize = 48 + OUTFOX_PACKET_OVERHEAD;
|
||||
const OUTFOX_REGULAR_PACKET_SIZE: usize = 2 * 1024 + OUTFOX_PACKET_OVERHEAD;
|
||||
const OUTFOX_EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + OUTFOX_PACKET_OVERHEAD;
|
||||
const OUTFOX_EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + OUTFOX_PACKET_OVERHEAD;
|
||||
const OUTFOX_EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + OUTFOX_PACKET_OVERHEAD;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum InvalidPacketSize {
|
||||
@@ -76,18 +74,6 @@ pub enum PacketSize {
|
||||
// for sending SURB-ACKs
|
||||
#[serde(rename = "outfox_ack")]
|
||||
OutfoxAckPacket = 7,
|
||||
|
||||
// for example for streaming fast and furious in uncompressed 10bit 4K HDR quality
|
||||
#[serde(rename = "outfox_extended32")]
|
||||
OutfoxExtendedPacket32 = 8,
|
||||
|
||||
// for example for streaming fast and furious in heavily compressed lossy RealPlayer quality
|
||||
#[serde(rename = "outfox_extended8")]
|
||||
OutfoxExtendedPacket8 = 9,
|
||||
|
||||
// for example for streaming fast and furious in compressed XviD quality
|
||||
#[serde(rename = "outfox_extended16")]
|
||||
OutfoxExtendedPacket16 = 10,
|
||||
}
|
||||
|
||||
impl PartialOrd for PacketSize {
|
||||
@@ -116,9 +102,6 @@ impl FromStr for PacketSize {
|
||||
"extended32" => Ok(Self::ExtendedPacket32),
|
||||
"outfox_regular" => Ok(Self::OutfoxRegularPacket),
|
||||
"outfox_ack" => Ok(Self::OutfoxAckPacket),
|
||||
"outfox_extended8" => Ok(Self::OutfoxExtendedPacket8),
|
||||
"outfox_extended16" => Ok(Self::OutfoxExtendedPacket16),
|
||||
"outfox_extended32" => Ok(Self::OutfoxExtendedPacket32),
|
||||
s => Err(InvalidPacketSize::UnknownExtendedPacketVariant {
|
||||
received: s.to_string(),
|
||||
}),
|
||||
@@ -136,9 +119,6 @@ impl Display for PacketSize {
|
||||
PacketSize::ExtendedPacket16 => write!(f, "extended16"),
|
||||
PacketSize::OutfoxRegularPacket => write!(f, "outfox_regular"),
|
||||
PacketSize::OutfoxAckPacket => write!(f, "outfox_ack"),
|
||||
PacketSize::OutfoxExtendedPacket32 => write!(f, "outfox_extended32"),
|
||||
PacketSize::OutfoxExtendedPacket8 => write!(f, "outfox_extended8"),
|
||||
PacketSize::OutfoxExtendedPacket16 => write!(f, "outfox_extended16"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,15 +145,6 @@ impl TryFrom<u8> for PacketSize {
|
||||
_ if value == (PacketSize::ExtendedPacket32 as u8) => Ok(Self::ExtendedPacket32),
|
||||
_ if value == (PacketSize::OutfoxRegularPacket as u8) => Ok(Self::OutfoxRegularPacket),
|
||||
_ if value == (PacketSize::OutfoxAckPacket as u8) => Ok(Self::OutfoxAckPacket),
|
||||
_ if value == (PacketSize::OutfoxExtendedPacket8 as u8) => {
|
||||
Ok(Self::OutfoxExtendedPacket8)
|
||||
}
|
||||
_ if value == (PacketSize::OutfoxExtendedPacket16 as u8) => {
|
||||
Ok(Self::OutfoxExtendedPacket16)
|
||||
}
|
||||
_ if value == (PacketSize::OutfoxExtendedPacket32 as u8) => {
|
||||
Ok(Self::OutfoxExtendedPacket32)
|
||||
}
|
||||
v => Err(InvalidPacketSize::UnknownPacketTag { received: v }),
|
||||
}
|
||||
}
|
||||
@@ -189,9 +160,6 @@ impl PacketSize {
|
||||
PacketSize::ExtendedPacket32 => EXTENDED_PACKET_SIZE_32,
|
||||
PacketSize::OutfoxRegularPacket => OUTFOX_REGULAR_PACKET_SIZE,
|
||||
PacketSize::OutfoxAckPacket => OUTFOX_ACK_PACKET_SIZE,
|
||||
PacketSize::OutfoxExtendedPacket8 => OUTFOX_EXTENDED_PACKET_SIZE_8,
|
||||
PacketSize::OutfoxExtendedPacket16 => OUTFOX_EXTENDED_PACKET_SIZE_16,
|
||||
PacketSize::OutfoxExtendedPacket32 => OUTFOX_EXTENDED_PACKET_SIZE_32,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,11 +170,7 @@ impl PacketSize {
|
||||
| PacketSize::ExtendedPacket8
|
||||
| PacketSize::ExtendedPacket16
|
||||
| PacketSize::ExtendedPacket32 => HEADER_SIZE,
|
||||
PacketSize::OutfoxRegularPacket
|
||||
| PacketSize::OutfoxAckPacket
|
||||
| PacketSize::OutfoxExtendedPacket8
|
||||
| PacketSize::OutfoxExtendedPacket16
|
||||
| PacketSize::OutfoxExtendedPacket32 => MIX_PARAMS_LEN,
|
||||
PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => MIX_PARAMS_LEN,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,11 +181,9 @@ impl PacketSize {
|
||||
| PacketSize::ExtendedPacket8
|
||||
| PacketSize::ExtendedPacket16
|
||||
| PacketSize::ExtendedPacket32 => PAYLOAD_OVERHEAD_SIZE,
|
||||
PacketSize::OutfoxRegularPacket
|
||||
| PacketSize::OutfoxAckPacket
|
||||
| PacketSize::OutfoxExtendedPacket8
|
||||
| PacketSize::OutfoxExtendedPacket16
|
||||
| PacketSize::OutfoxExtendedPacket32 => OUTFOX_PACKET_OVERHEAD - MIX_PARAMS_LEN,
|
||||
PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => {
|
||||
OUTFOX_PACKET_OVERHEAD - MIX_PARAMS_LEN // Mix params are calculated into the total overhead so we take them out here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,16 +206,12 @@ impl PacketSize {
|
||||
Ok(PacketSize::ExtendedPacket16)
|
||||
} else if PacketSize::ExtendedPacket32.size() == size {
|
||||
Ok(PacketSize::ExtendedPacket32)
|
||||
} else if PacketSize::OutfoxRegularPacket.size() == size {
|
||||
} else if PacketSize::OutfoxRegularPacket.size() == size
|
||||
|| PacketSize::OutfoxRegularPacket.size() == size + 6
|
||||
{
|
||||
Ok(PacketSize::OutfoxRegularPacket)
|
||||
} else if PacketSize::OutfoxAckPacket.size() == size {
|
||||
Ok(PacketSize::OutfoxAckPacket)
|
||||
} else if PacketSize::OutfoxExtendedPacket8.size() == size {
|
||||
Ok(PacketSize::OutfoxExtendedPacket8)
|
||||
} else if PacketSize::OutfoxExtendedPacket16.size() == size {
|
||||
Ok(PacketSize::OutfoxExtendedPacket16)
|
||||
} else if PacketSize::OutfoxExtendedPacket32.size() == size {
|
||||
Ok(PacketSize::OutfoxExtendedPacket32)
|
||||
} else {
|
||||
Err(InvalidPacketSize::UnknownPacketSize { received: size })
|
||||
}
|
||||
@@ -267,10 +225,7 @@ impl PacketSize {
|
||||
| PacketSize::OutfoxRegularPacket => false,
|
||||
PacketSize::ExtendedPacket8
|
||||
| PacketSize::ExtendedPacket16
|
||||
| PacketSize::ExtendedPacket32
|
||||
| PacketSize::OutfoxExtendedPacket8
|
||||
| PacketSize::OutfoxExtendedPacket16
|
||||
| PacketSize::OutfoxExtendedPacket32 => true,
|
||||
| PacketSize::ExtendedPacket32 => true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::PacketSize;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[error("{received} is not a valid packet mode tag")]
|
||||
pub struct InvalidPacketType {
|
||||
@@ -58,3 +60,17 @@ impl TryFrom<u8> for PacketType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PacketSize> for PacketType {
|
||||
fn from(s: PacketSize) -> Self {
|
||||
match s {
|
||||
PacketSize::RegularPacket => PacketType::Mix,
|
||||
PacketSize::AckPacket => PacketType::Mix,
|
||||
PacketSize::ExtendedPacket32 => PacketType::Mix,
|
||||
PacketSize::ExtendedPacket8 => PacketType::Mix,
|
||||
PacketSize::ExtendedPacket16 => PacketType::Mix,
|
||||
PacketSize::OutfoxRegularPacket => PacketType::Outfox,
|
||||
PacketSize::OutfoxAckPacket => PacketType::Outfox,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,12 +11,14 @@ use nym_sphinx_anonymous_replies::requests::{
|
||||
ReplyMessageContent,
|
||||
};
|
||||
use nym_sphinx_chunking::fragment::Fragment;
|
||||
use nym_sphinx_params::{PacketSize, ReplySurbKeyDigestAlgorithm};
|
||||
use nym_sphinx_params::{PacketSize, PacketType, ReplySurbKeyDigestAlgorithm};
|
||||
use rand::Rng;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use thiserror::Error;
|
||||
|
||||
pub(crate) const ACK_OVERHEAD: usize = MAX_NODE_ADDRESS_UNPADDED_LEN + PacketSize::AckPacket.size();
|
||||
pub(crate) const OUTFOX_ACK_OVERHEAD: usize =
|
||||
MAX_NODE_ADDRESS_UNPADDED_LEN + PacketSize::AckPacket.size();
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum NymMessageError {
|
||||
@@ -187,8 +189,15 @@ impl NymMessage {
|
||||
NymMessage::Reply(_) => ReplySurbKeyDigestAlgorithm::output_size(),
|
||||
};
|
||||
|
||||
let packet_type = PacketType::from(packet_size);
|
||||
|
||||
// each packet will contain an ack + variant specific data (as described above)
|
||||
packet_size.plaintext_size() - ACK_OVERHEAD - variant_overhead
|
||||
match packet_type {
|
||||
PacketType::Outfox => {
|
||||
packet_size.plaintext_size() - OUTFOX_ACK_OVERHEAD - variant_overhead
|
||||
}
|
||||
_ => packet_size.plaintext_size() - ACK_OVERHEAD - variant_overhead,
|
||||
}
|
||||
}
|
||||
|
||||
/// Length of the actual (from the **message** point of view) data that is available in each packet.
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::message::{NymMessage, ACK_OVERHEAD};
|
||||
use crate::message::{NymMessage, ACK_OVERHEAD, OUTFOX_ACK_OVERHEAD};
|
||||
use crate::NymPayloadBuilder;
|
||||
use log::info;
|
||||
use nym_crypto::asymmetric::encryption;
|
||||
use nym_crypto::Digest;
|
||||
use nym_sphinx_acknowledgements::surb_ack::SurbAck;
|
||||
@@ -114,7 +113,10 @@ pub trait FragmentPreparer {
|
||||
// each reply attaches the digest of the encryption key so that the recipient could
|
||||
// lookup correct key for decryption,
|
||||
let reply_overhead = ReplySurbKeyDigestAlgorithm::output_size();
|
||||
let expected_plaintext = fragment.serialized_size() + ACK_OVERHEAD + reply_overhead;
|
||||
let expected_plaintext = match packet_type {
|
||||
PacketType::Outfox => fragment.serialized_size() + OUTFOX_ACK_OVERHEAD + reply_overhead,
|
||||
_ => fragment.serialized_size() + ACK_OVERHEAD + reply_overhead,
|
||||
};
|
||||
|
||||
// the reason we're unwrapping (or rather 'expecting') here rather than handling the error
|
||||
// more gracefully is that this error should never be reached as it implies incorrect chunking
|
||||
@@ -157,7 +159,7 @@ pub trait FragmentPreparer {
|
||||
// well as the total delay of the ack packet.
|
||||
// we don't know the delays inside the reply surbs so we use best-effort estimation from our poisson distribution
|
||||
total_delay: expected_forward_delay + ack_delay,
|
||||
mix_packet: MixPacket::new(first_hop_address, sphinx_packet, Default::default()),
|
||||
mix_packet: MixPacket::new(first_hop_address, sphinx_packet, packet_type),
|
||||
fragment_identifier,
|
||||
})
|
||||
}
|
||||
@@ -188,12 +190,16 @@ pub trait FragmentPreparer {
|
||||
packet_recipient: &Recipient,
|
||||
packet_type: PacketType,
|
||||
) -> Result<PreparedFragment, NymTopologyError> {
|
||||
info!("Preparing {packet_type} packet for sending");
|
||||
// each plain or repliable packet (i.e. not a reply) attaches an ephemeral public key so that the recipient
|
||||
// could perform diffie-hellman with its own keys followed by a kdf to re-derive
|
||||
// the packet encryption key
|
||||
let non_reply_overhead = encryption::PUBLIC_KEY_SIZE;
|
||||
let expected_plaintext = fragment.serialized_size() + ACK_OVERHEAD + non_reply_overhead;
|
||||
let expected_plaintext = match packet_type {
|
||||
PacketType::Outfox => {
|
||||
fragment.serialized_size() + OUTFOX_ACK_OVERHEAD + non_reply_overhead
|
||||
}
|
||||
_ => fragment.serialized_size() + ACK_OVERHEAD + non_reply_overhead,
|
||||
};
|
||||
|
||||
// the reason we're unwrapping (or rather 'expecting') here rather than handling the error
|
||||
// more gracefully is that this error should never be reached as it implies incorrect chunking
|
||||
@@ -235,7 +241,8 @@ pub trait FragmentPreparer {
|
||||
PacketType::Outfox => NymPacket::outfox_build(
|
||||
packet_payload,
|
||||
route.as_slice(),
|
||||
Some(packet_size.payload_size()),
|
||||
&destination,
|
||||
Some(packet_size.plaintext_size()),
|
||||
)?,
|
||||
PacketType::Mix => NymPacket::sphinx_build(
|
||||
packet_size.payload_size(),
|
||||
@@ -262,7 +269,7 @@ pub trait FragmentPreparer {
|
||||
// well as the total delay of the ack packet.
|
||||
// note that the last hop of the packet is a gateway that does not do any delays
|
||||
total_delay: delays.iter().take(delays.len() - 1).sum::<Delay>() + ack_delay,
|
||||
mix_packet: MixPacket::new(first_hop_address, packet, Default::default()),
|
||||
mix_packet: MixPacket::new(first_hop_address, packet, packet_type),
|
||||
fragment_identifier,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ impl NymPayloadBuilder {
|
||||
// where variant-specific data is as follows:
|
||||
// for replies it would be the digest of the encryption key used
|
||||
// for 'regular' messages it would be the public component used in DH later used in the KDF
|
||||
|
||||
Ok(NymPayload(
|
||||
surb_ack_bytes
|
||||
.into_iter()
|
||||
|
||||
@@ -5,7 +5,7 @@ pub use nym_outfox::{
|
||||
constants::MIX_PARAMS_LEN, constants::OUTFOX_PACKET_OVERHEAD, error::OutfoxError,
|
||||
};
|
||||
// re-exporting types and constants available in sphinx
|
||||
use nym_outfox::packet::OutfoxPacket;
|
||||
use nym_outfox::packet::{OutfoxPacket, OutfoxProcessedPacket};
|
||||
pub use sphinx_packet::{
|
||||
constants::{
|
||||
self, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, MAX_PATH_LENGTH, NODE_ADDRESS_LENGTH,
|
||||
@@ -41,6 +41,11 @@ pub enum NymPacket {
|
||||
Outfox(OutfoxPacket),
|
||||
}
|
||||
|
||||
pub enum NymProcessedPacket {
|
||||
Sphinx(ProcessedPacket),
|
||||
Outfox(OutfoxProcessedPacket),
|
||||
}
|
||||
|
||||
impl fmt::Debug for NymPacket {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match &self {
|
||||
@@ -77,11 +82,13 @@ impl NymPacket {
|
||||
pub fn outfox_build<M: AsRef<[u8]>>(
|
||||
payload: M,
|
||||
route: &[Node],
|
||||
destination: &Destination,
|
||||
size: Option<usize>,
|
||||
) -> Result<NymPacket, NymPacketError> {
|
||||
Ok(NymPacket::Outfox(OutfoxPacket::build(
|
||||
payload,
|
||||
route.try_into()?,
|
||||
destination,
|
||||
size,
|
||||
)?))
|
||||
}
|
||||
@@ -108,10 +115,21 @@ impl NymPacket {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process(self, node_secret_key: &PrivateKey) -> Result<ProcessedPacket, NymPacketError> {
|
||||
pub fn process(
|
||||
self,
|
||||
node_secret_key: &PrivateKey,
|
||||
) -> Result<NymProcessedPacket, NymPacketError> {
|
||||
match self {
|
||||
NymPacket::Sphinx(packet) => Ok(packet.process(node_secret_key)?),
|
||||
NymPacket::Outfox(_packet) => todo!(),
|
||||
NymPacket::Sphinx(packet) => {
|
||||
Ok(NymProcessedPacket::Sphinx(packet.process(node_secret_key)?))
|
||||
}
|
||||
NymPacket::Outfox(mut packet) => {
|
||||
let next_address = packet.decode_next_layer(node_secret_key)?;
|
||||
Ok(NymProcessedPacket::Outfox(OutfoxProcessedPacket::new(
|
||||
packet,
|
||||
next_address,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,13 +499,13 @@ impl SocksClient {
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
info!(
|
||||
debug!(
|
||||
"Starting proxy for {} (id: {})",
|
||||
remote_address.clone(),
|
||||
self.connection_id
|
||||
);
|
||||
self.run_proxy(mix_receiver, remote_address.clone()).await;
|
||||
info!(
|
||||
debug!(
|
||||
"Proxy for {} is finished (id: {})",
|
||||
remote_address, self.connection_id
|
||||
);
|
||||
|
||||
@@ -78,7 +78,7 @@ impl SocksRequest {
|
||||
where
|
||||
R: AsyncRead + Unpin,
|
||||
{
|
||||
log::info!("read from stream socks5");
|
||||
log::trace!("read from stream socks5");
|
||||
|
||||
let mut packet = [0u8; 4];
|
||||
// Read a byte from the stream and determine the version being requested
|
||||
|
||||
@@ -9,7 +9,6 @@ use nym_sphinx_addressing::nodes::NodeIdentity;
|
||||
use rand::prelude::SliceRandom;
|
||||
use nym_sphinx_types::{Node as SphinxNode, NymPacketError};
|
||||
use rand::{CryptoRng, Rng};
|
||||
use std::array::TryFromSliceError;
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
Reference in New Issue
Block a user