mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-07-25 11:42:50 +02:00
Some VL1 work, and reorg the header in ZSSP to make backward compatibility easy.
This commit is contained in:
parent
115c1c6c56
commit
887585f6fa
4 changed files with 115 additions and 129 deletions
|
@ -427,11 +427,11 @@ impl<H: Host> Session<H> {
|
|||
let fragment_size = fragment_data_size + HEADER_SIZE;
|
||||
c.crypt(&data[..fragment_data_size], &mut mtu_buffer[HEADER_SIZE..fragment_size]);
|
||||
data = &data[fragment_data_size..];
|
||||
armor_header(mtu_buffer, &self.header_check_cipher);
|
||||
set_header_mac(mtu_buffer, &self.header_check_cipher);
|
||||
send(&mut mtu_buffer[..fragment_size]);
|
||||
|
||||
debug_assert!(header[7].wrapping_shr(2) < 63);
|
||||
header[7] += 0x04; // increment fragment number
|
||||
debug_assert!(header[15].wrapping_shr(2) < 63);
|
||||
header[15] += 0x04; // increment fragment number
|
||||
mtu_buffer[..HEADER_SIZE].copy_from_slice(&header);
|
||||
|
||||
if data.len() <= last_fragment_data_mtu {
|
||||
|
@ -445,7 +445,7 @@ impl<H: Host> Session<H> {
|
|||
c.crypt(data, &mut mtu_buffer[HEADER_SIZE..gcm_tag_idx]);
|
||||
mtu_buffer[gcm_tag_idx..packet_len].copy_from_slice(&c.finish_encrypt());
|
||||
|
||||
armor_header(mtu_buffer, &self.header_check_cipher);
|
||||
set_header_mac(mtu_buffer, &self.header_check_cipher);
|
||||
send(&mut mtu_buffer[..packet_len]);
|
||||
|
||||
key.return_send_cipher(c);
|
||||
|
@ -562,11 +562,17 @@ impl<H: Host> ReceiveContext<H> {
|
|||
return Err(Error::InvalidPacket);
|
||||
}
|
||||
|
||||
if let Some(local_session_id) = SessionId::new_from_u64(memory::u64_from_le_bytes(incoming_packet) & SessionId::MAX_BIT_MASK) {
|
||||
let counter = memory::u32_from_le_bytes(incoming_packet);
|
||||
let packet_type_fragment_info = memory::u16_from_le_bytes(&incoming_packet[14..16]);
|
||||
let packet_type = (packet_type_fragment_info & 0x0f) as u8;
|
||||
let fragment_count = ((packet_type_fragment_info.wrapping_shr(4) + 1) as u8) & 63;
|
||||
let fragment_no = packet_type_fragment_info.wrapping_shr(10) as u8;
|
||||
|
||||
if let Some(local_session_id) =
|
||||
SessionId::new_from_u64(memory::u64_from_le_bytes(&incoming_packet[8..16]) & SessionId::MAX_BIT_MASK)
|
||||
{
|
||||
if let Some(session) = host.session_lookup(local_session_id) {
|
||||
if let Some((packet_type, fragment_count, fragment_no, counter)) =
|
||||
dearmor_header(incoming_packet, &session.header_check_cipher)
|
||||
{
|
||||
if check_header_mac(incoming_packet, &session.header_check_cipher) {
|
||||
let pseudoheader = Pseudoheader::make(u64::from(local_session_id), packet_type, counter);
|
||||
if fragment_count > 1 {
|
||||
if fragment_count <= (MAX_FRAGMENTS as u8) && fragment_no < fragment_count {
|
||||
|
@ -613,9 +619,7 @@ impl<H: Host> ReceiveContext<H> {
|
|||
}
|
||||
} else {
|
||||
unlikely_branch();
|
||||
if let Some((packet_type, fragment_count, fragment_no, counter)) =
|
||||
dearmor_header(incoming_packet, &self.incoming_init_header_check_cipher)
|
||||
{
|
||||
if check_header_mac(incoming_packet, &self.incoming_init_header_check_cipher) {
|
||||
let pseudoheader = Pseudoheader::make(0, packet_type, counter);
|
||||
if fragment_count > 1 {
|
||||
let mut defrag = self.initial_offer_defrag.lock();
|
||||
|
@ -1152,7 +1156,7 @@ impl<H: Host> ReceiveContext<H> {
|
|||
reply_buf[HEADER_SIZE..].copy_from_slice(&c.finish_encrypt());
|
||||
key.return_send_cipher(c);
|
||||
|
||||
armor_header(&mut reply_buf, &session.header_check_cipher);
|
||||
set_header_mac(&mut reply_buf, &session.header_check_cipher);
|
||||
send(&mut reply_buf);
|
||||
|
||||
let mut state = RwLockUpgradableReadGuard::upgrade(state);
|
||||
|
@ -1351,6 +1355,15 @@ fn create_initial_offer<SendFunction: FnMut(&mut [u8])>(
|
|||
}))
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C, packed)]
|
||||
struct PackedHeader {
|
||||
counter: u32,
|
||||
recipient_session_id_low32: u32,
|
||||
recipient_session_id_high16_packet_type_fragment_info: u32,
|
||||
zero: u32,
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn create_packet_header(
|
||||
header: &mut [u8],
|
||||
|
@ -1365,17 +1378,20 @@ fn create_packet_header(
|
|||
debug_assert!(header.len() >= HEADER_SIZE);
|
||||
debug_assert!(mtu >= MIN_MTU);
|
||||
debug_assert!(packet_len >= MIN_PACKET_SIZE);
|
||||
debug_assert!(fragment_count <= MAX_FRAGMENTS);
|
||||
debug_assert!(fragment_count > 0);
|
||||
debug_assert!(packet_type <= 0x0f); // packet type is 4 bits
|
||||
debug_assert!(recipient_session_id <= 0xffffffffffff); // session ID is 48 bits
|
||||
|
||||
if fragment_count <= MAX_FRAGMENTS {
|
||||
header[0..8].copy_from_slice(
|
||||
&(recipient_session_id | (packet_type as u64).wrapping_shl(48) | ((fragment_count - 1) as u64).wrapping_shl(52)).to_le_bytes(),
|
||||
);
|
||||
header[8..12].copy_from_slice(&counter.to_u32().to_le_bytes());
|
||||
header[12..16].fill(0);
|
||||
header[..16].copy_from_slice(memory::as_byte_array::<[u32; 4], 16>(&[
|
||||
counter.to_u32().to_le(),
|
||||
0,
|
||||
(recipient_session_id as u32).to_le(),
|
||||
((recipient_session_id.wrapping_shr(32) as u32)
|
||||
| (packet_type as u32).wrapping_shl(16)
|
||||
| ((fragment_count - 1) as u32).wrapping_shl(20))
|
||||
.to_le(),
|
||||
]));
|
||||
Ok(())
|
||||
} else {
|
||||
unlikely_branch();
|
||||
|
@ -1395,11 +1411,11 @@ fn send_with_fragmentation<SendFunction: FnMut(&mut [u8])>(
|
|||
let mut header: [u8; 16] = packet[..HEADER_SIZE].try_into().unwrap();
|
||||
loop {
|
||||
let fragment = &mut packet[fragment_start..fragment_end];
|
||||
armor_header(fragment, header_check_cipher);
|
||||
set_header_mac(fragment, header_check_cipher);
|
||||
send(fragment);
|
||||
if fragment_end < packet_len {
|
||||
debug_assert!(header[7].wrapping_shr(2) < 63);
|
||||
header[7] += 0x04; // increment fragment number
|
||||
debug_assert!(header[15].wrapping_shr(2) < 63);
|
||||
header[15] += 0x04; // increment fragment number
|
||||
fragment_start = fragment_end - HEADER_SIZE;
|
||||
fragment_end = (fragment_start + mtu).min(packet_len);
|
||||
packet[fragment_start..(fragment_start + HEADER_SIZE)].copy_from_slice(&header);
|
||||
|
@ -1410,45 +1426,21 @@ fn send_with_fragmentation<SendFunction: FnMut(&mut [u8])>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Encrypt everything in header after session ID using AES-CTR and the second 16 bytes as a nonce.
|
||||
/// The last four bytes of the header must be zero, so this also embeds a small header MAC.
|
||||
/// Set 32-bit header MAC.
|
||||
#[inline(always)]
|
||||
fn armor_header(packet: &mut [u8], header_check_cipher: &Aes) {
|
||||
fn set_header_mac(packet: &mut [u8], header_check_cipher: &Aes) {
|
||||
debug_assert!(packet.len() >= MIN_PACKET_SIZE);
|
||||
let mut header_pad = 0u128.to_ne_bytes();
|
||||
header_check_cipher.encrypt_block(&packet[16..32], &mut header_pad);
|
||||
packet[SESSION_ID_SIZE..HEADER_SIZE]
|
||||
.iter_mut()
|
||||
.zip(header_pad.iter())
|
||||
.for_each(|(x, y)| *x ^= *y);
|
||||
let mut header_mac = 0u128.to_ne_bytes();
|
||||
header_check_cipher.encrypt_block(&packet[8..24], &mut header_mac);
|
||||
packet[4..8].copy_from_slice(&header_mac[..4]);
|
||||
}
|
||||
|
||||
/// Dearmor the armored part of the header and return it if the 32-bit MAC matches.
|
||||
fn dearmor_header(packet: &[u8], header_check_cipher: &Aes) -> Option<(u8, u8, u8, u32)> {
|
||||
/// Check 32-bit header MAC on an incoming packet.
|
||||
fn check_header_mac(packet: &[u8], header_check_cipher: &Aes) -> bool {
|
||||
debug_assert!(packet.len() >= MIN_PACKET_SIZE);
|
||||
let mut header_pad = 0u128.to_ne_bytes();
|
||||
header_check_cipher.encrypt_block(&packet[16..32], &mut header_pad);
|
||||
let header_pad = u128::from_ne_bytes(header_pad);
|
||||
|
||||
#[cfg(target_endian = "little")]
|
||||
let (header_0_8, header_8_16) = {
|
||||
let header = memory::u128_from_ne_bytes(packet) ^ header_pad.wrapping_shl(48);
|
||||
(header as u64, header.wrapping_shr(64) as u64)
|
||||
};
|
||||
#[cfg(target_endian = "big")]
|
||||
let (header_0_8, header_8_16) = {
|
||||
let header = memory::u128_from_ne_bytes(packet) ^ header_pad.wrapping_shr(48);
|
||||
((header.wrapping_shr(64) as u64).swap_bytes(), (header as u64).swap_bytes())
|
||||
};
|
||||
|
||||
if header_8_16.wrapping_shr(32) == 0 {
|
||||
let packet_type = (header_0_8.wrapping_shr(48) as u8) & 15;
|
||||
let fragment_count = ((header_0_8.wrapping_shr(52) as u8) & 63).wrapping_add(1);
|
||||
let fragment_no = (header_0_8.wrapping_shr(58) as u8) & 63;
|
||||
Some((packet_type, fragment_count, fragment_no, header_8_16 as u32))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
let mut header_mac = 0u128.to_ne_bytes();
|
||||
header_check_cipher.encrypt_block(&packet[8..24], &mut header_mac);
|
||||
memory::u32_from_ne_bytes(&packet[4..8]) == memory::u32_from_ne_bytes(&header_mac)
|
||||
}
|
||||
|
||||
/// Parse KEY_OFFER and KEY_COUNTER_OFFER starting after the unencrypted public key part.
|
||||
|
|
|
@ -155,7 +155,7 @@ struct BackgroundTaskIntervals {
|
|||
struct RootInfo<SI: SystemInterface> {
|
||||
sets: HashMap<String, RootSet>,
|
||||
roots: HashMap<Arc<Peer<SI>>, Vec<Endpoint>>,
|
||||
my_root_sets: Option<Vec<u8>>,
|
||||
this_root_sets: Option<Vec<u8>>,
|
||||
sets_modified: bool,
|
||||
online: bool,
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ impl<SI: SystemInterface> Node<SI> {
|
|||
roots: RwLock::new(RootInfo {
|
||||
sets: HashMap::new(),
|
||||
roots: HashMap::new(),
|
||||
my_root_sets: None,
|
||||
this_root_sets: None,
|
||||
sets_modified: false,
|
||||
online: false,
|
||||
}),
|
||||
|
@ -504,7 +504,7 @@ impl<SI: SystemInterface> Node<SI> {
|
|||
if !old_root_identities.eq(&new_root_identities) {
|
||||
let mut roots = self.roots.write();
|
||||
roots.roots = new_roots;
|
||||
roots.my_root_sets = my_root_sets;
|
||||
roots.this_root_sets = my_root_sets;
|
||||
si.event(Event::UpdatedRoots(old_root_identities, new_root_identities));
|
||||
}
|
||||
}
|
||||
|
@ -729,14 +729,17 @@ impl<SI: SystemInterface> Node<SI> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the current "best" root from among this node's trusted roots.
|
||||
pub fn best_root(&self) -> Option<Arc<Peer<SI>>> {
|
||||
self.best_root.read().clone()
|
||||
}
|
||||
|
||||
/// Check whether this peer is a root according to any root set trusted by this node.
|
||||
pub fn is_peer_root(&self, peer: &Peer<SI>) -> bool {
|
||||
self.roots.read().roots.keys().any(|p| p.identity.eq(&peer.identity))
|
||||
}
|
||||
|
||||
/// Called when a remote node sends us a root set update.
|
||||
pub(crate) fn remote_update_root_set(&self, received_from: &Identity, rs: RootSet) {
|
||||
let mut roots = self.roots.write();
|
||||
if let Some(entry) = roots.sets.get_mut(&rs.name) {
|
||||
|
@ -763,23 +766,27 @@ impl<SI: SystemInterface> Node<SI> {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Returns whether or not this node has any root sets defined.
|
||||
pub fn has_roots_defined(&self) -> bool {
|
||||
self.roots.read().sets.iter().any(|rs| !rs.1.members.is_empty())
|
||||
}
|
||||
|
||||
/// Get the root sets that this node trusts.
|
||||
pub fn root_sets(&self) -> Vec<RootSet> {
|
||||
self.roots.read().sets.values().cloned().collect()
|
||||
}
|
||||
|
||||
pub(crate) fn my_root_sets(&self) -> Option<Vec<u8>> {
|
||||
self.roots.read().my_root_sets.clone()
|
||||
/// Get the root set(s) to which this node belongs if it is a root.
|
||||
pub(crate) fn this_root_sets_as_bytes(&self) -> Option<Vec<u8>> {
|
||||
self.roots.read().this_root_sets.clone()
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub(crate) fn this_node_is_root(&self) -> bool {
|
||||
self.roots.read().my_root_sets.is_some()
|
||||
/// Returns true if this node is a member of a root set (that it knows about).
|
||||
pub fn this_node_is_root(&self) -> bool {
|
||||
self.roots.read().this_root_sets.is_some()
|
||||
}
|
||||
|
||||
/// Get the canonical Path object corresponding to an endpoint.
|
||||
pub(crate) fn canonical_path(
|
||||
&self,
|
||||
ep: &Endpoint,
|
||||
|
@ -788,13 +795,13 @@ impl<SI: SystemInterface> Node<SI> {
|
|||
time_ticks: i64,
|
||||
) -> Arc<Path<SI>> {
|
||||
if let Some(path) = self.paths.read().get(&PathKey::Ref(ep, local_socket)) {
|
||||
return path.clone();
|
||||
path.clone()
|
||||
} else {
|
||||
self.paths
|
||||
.write()
|
||||
.entry(PathKey::Copied(ep.clone(), local_socket.clone()))
|
||||
.or_insert_with(|| Arc::new(Path::new(ep.clone(), local_socket.clone(), local_interface.clone(), time_ticks)))
|
||||
.clone()
|
||||
}
|
||||
return self
|
||||
.paths
|
||||
.write()
|
||||
.entry(PathKey::Copied(ep.clone(), local_socket.clone()))
|
||||
.or_insert_with(|| Arc::new(Path::new(ep.clone(), local_socket.clone(), local_interface.clone(), time_ticks)))
|
||||
.clone();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::sync::{Arc, Weak};
|
|||
use parking_lot::{Mutex, RwLock};
|
||||
|
||||
use zerotier_crypto::poly1305;
|
||||
use zerotier_crypto::random::next_u64_secure;
|
||||
use zerotier_crypto::random;
|
||||
use zerotier_crypto::salsa::Salsa;
|
||||
use zerotier_crypto::secret::Secret;
|
||||
use zerotier_utils::memory::array_range;
|
||||
|
@ -25,50 +25,35 @@ use crate::{VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION};
|
|||
|
||||
pub(crate) const SERVICE_INTERVAL_MS: i64 = 10000;
|
||||
|
||||
pub struct Peer<SI: SystemInterface> {
|
||||
pub identity: Identity,
|
||||
|
||||
static_symmetric_key: SymmetricSecret,
|
||||
paths: Mutex<Vec<PeerPath<SI>>>,
|
||||
|
||||
pub(crate) last_send_time_ticks: AtomicI64,
|
||||
pub(crate) last_receive_time_ticks: AtomicI64,
|
||||
pub(crate) last_hello_reply_time_ticks: AtomicI64,
|
||||
pub(crate) last_forward_time_ticks: AtomicI64,
|
||||
pub(crate) create_time_ticks: i64,
|
||||
|
||||
random_ticks_offset: u32,
|
||||
message_id_counter: AtomicU64,
|
||||
remote_node_info: RwLock<RemoteNodeInfo>,
|
||||
}
|
||||
|
||||
struct PeerPath<SI: SystemInterface> {
|
||||
path: Weak<Path<SI>>,
|
||||
last_receive_time_ticks: i64,
|
||||
}
|
||||
|
||||
struct RemoteNodeInfo {
|
||||
remote_instance_id: [u8; 16],
|
||||
reported_local_endpoints: HashMap<Endpoint, i64>,
|
||||
remote_version: u64,
|
||||
remote_protocol_version: u8,
|
||||
remote_version: (u8, u8, u16),
|
||||
}
|
||||
|
||||
/// A remote peer known to this node.
|
||||
///
|
||||
/// Equality and hashing is implemented in terms of the identity.
|
||||
pub struct Peer<SI: SystemInterface> {
|
||||
// This peer's identity.
|
||||
pub identity: Identity,
|
||||
|
||||
// Static shared secret computed from agreement with identity.
|
||||
identity_symmetric_key: SymmetricSecret,
|
||||
|
||||
// Paths sorted in descending order of quality / preference.
|
||||
paths: Mutex<Vec<PeerPath<SI>>>,
|
||||
|
||||
// Statistics and times of events.
|
||||
pub(crate) last_send_time_ticks: AtomicI64,
|
||||
pub(crate) last_receive_time_ticks: AtomicI64,
|
||||
pub(crate) last_hello_reply_time_ticks: AtomicI64,
|
||||
pub(crate) last_forward_time_ticks: AtomicI64,
|
||||
pub(crate) last_incoming_message_id: AtomicU64,
|
||||
pub(crate) create_time_ticks: i64,
|
||||
|
||||
// A random offset added to ticks sent to this peer to avoid disclosing the actual tick count.
|
||||
random_ticks_offset: u64,
|
||||
|
||||
// Counter for assigning sequential message IDs.
|
||||
message_id_counter: AtomicU64,
|
||||
|
||||
// Other information reported by remote node.
|
||||
remote_node_info: RwLock<RemoteNodeInfo>,
|
||||
}
|
||||
|
||||
/// Attempt AEAD packet encryption and MAC validation. Returns message ID on success.
|
||||
/// Attempt ZeroTier V1 protocol AEAD packet encryption and MAC validation. Returns message ID on success.
|
||||
fn try_aead_decrypt(
|
||||
secret: &SymmetricSecret,
|
||||
packet_frag0_payload_bytes: &[u8],
|
||||
|
@ -185,7 +170,7 @@ impl<SI: SystemInterface> Peer<SI> {
|
|||
this_node_identity.agree(&id).map(|static_secret| -> Self {
|
||||
Self {
|
||||
identity: id,
|
||||
identity_symmetric_key: SymmetricSecret::new(static_secret),
|
||||
static_symmetric_key: SymmetricSecret::new(static_secret),
|
||||
paths: Mutex::new(Vec::with_capacity(4)),
|
||||
last_send_time_ticks: AtomicI64::new(crate::util::NEVER_HAPPENED_TICKS),
|
||||
last_receive_time_ticks: AtomicI64::new(crate::util::NEVER_HAPPENED_TICKS),
|
||||
|
@ -193,29 +178,23 @@ impl<SI: SystemInterface> Peer<SI> {
|
|||
last_hello_reply_time_ticks: AtomicI64::new(crate::util::NEVER_HAPPENED_TICKS),
|
||||
last_incoming_message_id: AtomicU64::new(0),
|
||||
create_time_ticks: time_ticks,
|
||||
random_ticks_offset: next_u64_secure(),
|
||||
message_id_counter: AtomicU64::new(next_u64_secure()),
|
||||
random_ticks_offset: random::xorshift64_random() as u32,
|
||||
message_id_counter: AtomicU64::new(random::xorshift64_random()),
|
||||
remote_node_info: RwLock::new(RemoteNodeInfo {
|
||||
remote_instance_id: [0_u8; 16],
|
||||
reported_local_endpoints: HashMap::new(),
|
||||
remote_version: 0,
|
||||
remote_protocol_version: 0,
|
||||
remote_version: (0, 0, 0),
|
||||
}),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the remote version of this peer: major, minor, revision, and build.
|
||||
/// Get the remote version of this peer: major, minor, revision.
|
||||
/// Returns None if it's not yet known.
|
||||
pub fn version(&self) -> Option<[u16; 4]> {
|
||||
pub fn version(&self) -> Option<(u8, u8, u16)> {
|
||||
let rv = self.remote_node_info.read().remote_version;
|
||||
if rv != 0 {
|
||||
Some([
|
||||
rv.wrapping_shr(48) as u16,
|
||||
rv.wrapping_shr(32) as u16,
|
||||
rv.wrapping_shr(16) as u16,
|
||||
rv as u16,
|
||||
])
|
||||
if rv.0 != 0 || rv.1 != 0 || rv.2 != 0 {
|
||||
Some(rv)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -433,7 +412,7 @@ impl<SI: SystemInterface> Peer<SI> {
|
|||
v1::CIPHER_AES_GMAC_SIV
|
||||
};
|
||||
|
||||
let mut aes_gmac_siv = self.identity_symmetric_key.aes_gmac_siv.get();
|
||||
let mut aes_gmac_siv = self.static_symmetric_key.aes_gmac_siv.get();
|
||||
aes_gmac_siv.encrypt_init(&self.next_message_id().to_ne_bytes());
|
||||
aes_gmac_siv.encrypt_set_aad(&v1::get_packet_aad_bytes(
|
||||
self.identity.address,
|
||||
|
@ -543,14 +522,14 @@ impl<SI: SystemInterface> Peer<SI> {
|
|||
f.1.version_major = VERSION_MAJOR;
|
||||
f.1.version_minor = VERSION_MINOR;
|
||||
f.1.version_revision = VERSION_REVISION.to_be_bytes();
|
||||
f.1.timestamp = (time_ticks as u64).wrapping_add(self.random_ticks_offset).to_be_bytes();
|
||||
f.1.timestamp = (time_ticks as u64).wrapping_add(self.random_ticks_offset as u64).to_be_bytes();
|
||||
}
|
||||
|
||||
debug_assert_eq!(packet.len(), 41);
|
||||
assert!(packet.append_bytes((&node.identity.to_public_bytes()).into()).is_ok());
|
||||
|
||||
let (_, poly1305_key) = salsa_poly_create(
|
||||
&self.identity_symmetric_key,
|
||||
&self.static_symmetric_key,
|
||||
packet.struct_at::<v1::PacketHeader>(0).unwrap(),
|
||||
packet.len(),
|
||||
);
|
||||
|
@ -611,7 +590,7 @@ impl<SI: SystemInterface> Peer<SI> {
|
|||
let mut payload = PacketBuffer::new();
|
||||
|
||||
let message_id = if let Some(message_id2) = try_aead_decrypt(
|
||||
&self.identity_symmetric_key,
|
||||
&self.static_symmetric_key,
|
||||
packet_frag0_payload_bytes,
|
||||
packet_header,
|
||||
fragments,
|
||||
|
@ -684,9 +663,6 @@ impl<SI: SystemInterface> Peer<SI> {
|
|||
verbs::VL1_USER_MESSAGE => self.handle_incoming_user_message(si, node, time_ticks, source_path, &payload).await,
|
||||
_ => ph.handle_packet(self, &source_path, verb, &payload).await,
|
||||
} {
|
||||
// This needs to be saved AFTER processing the packet since some message types may use it to try to filter for replays.
|
||||
self.last_incoming_message_id.store(message_id, Ordering::Relaxed);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -721,9 +697,11 @@ impl<SI: SystemInterface> Peer<SI> {
|
|||
{
|
||||
let mut remote_node_info = self.remote_node_info.write();
|
||||
remote_node_info.remote_protocol_version = hello_fixed_headers.version_proto;
|
||||
remote_node_info.remote_version = (hello_fixed_headers.version_major as u64).wrapping_shl(48)
|
||||
| (hello_fixed_headers.version_minor as u64).wrapping_shl(32)
|
||||
| (u16::from_be_bytes(hello_fixed_headers.version_revision) as u64).wrapping_shl(16);
|
||||
remote_node_info.remote_version = (
|
||||
hello_fixed_headers.version_major,
|
||||
hello_fixed_headers.version_minor,
|
||||
u16::from_be_bytes(hello_fixed_headers.version_revision),
|
||||
);
|
||||
}
|
||||
|
||||
let mut packet = PacketBuffer::new();
|
||||
|
|
|
@ -80,6 +80,11 @@ pub mod verbs {
|
|||
pub const VL1_PUSH_DIRECT_PATHS: u8 = 0x10;
|
||||
pub const VL1_USER_MESSAGE: u8 = 0x14;
|
||||
|
||||
pub const VL2_VERB_MULTICAST_LIKE: u8 = 0x09;
|
||||
pub const VL2_VERB_NETWORK_CONFIG_REQUEST: u8 = 0x0b;
|
||||
pub const VL2_VERB_NETWORK_CONFIG: u8 = 0x0c;
|
||||
pub const VL2_VERB_MULTICAST_GATHER: u8 = 0x0d;
|
||||
|
||||
pub fn name(verb: u8) -> &'static str {
|
||||
match verb {
|
||||
VL1_NOP => "VL1_NOP",
|
||||
|
@ -91,6 +96,10 @@ pub mod verbs {
|
|||
VL1_ECHO => "VL1_ECHO",
|
||||
VL1_PUSH_DIRECT_PATHS => "VL1_PUSH_DIRECT_PATHS",
|
||||
VL1_USER_MESSAGE => "VL1_USER_MESSAGE",
|
||||
VL2_VERB_MULTICAST_LIKE => "VL2_VERB_MULTICAST_LIKE",
|
||||
VL2_VERB_NETWORK_CONFIG_REQUEST => "VL2_VERB_NETWORK_CONFIG_REQUEST",
|
||||
VL2_VERB_NETWORK_CONFIG => "VL2_VERB_NETWORK_CONFIG",
|
||||
VL2_VERB_MULTICAST_GATHER => "VL2_VERB_MULTICAST_GATHER",
|
||||
_ => "???",
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue