Comm with chip-tool

This commit is contained in:
ivmarkov 2023-04-24 21:41:16 +00:00
parent 36011c2e3c
commit 8b3bb9527c
7 changed files with 335 additions and 146 deletions

View file

@ -28,8 +28,8 @@ use matter::data_model::sdm::dev_att::DevAttDataFetcher;
use matter::interaction_model::core::InteractionModel; use matter::interaction_model::core::InteractionModel;
use matter::secure_channel::spake2p::VerifierData; use matter::secure_channel::spake2p::VerifierData;
use matter::transport::{ use matter::transport::{
mgr::RecvAction, mgr::TransportMgr, packet::Packet, packet::MAX_RX_BUF_SIZE, mgr::RecvAction, mgr::TransportMgr, packet::MAX_RX_BUF_SIZE, packet::MAX_TX_BUF_SIZE,
packet::MAX_TX_BUF_SIZE, udp::UdpListener, udp::UdpListener,
}; };
mod dev_att; mod dev_att;
@ -48,7 +48,7 @@ fn main() {
device_name: "OnOff Light", device_name: "OnOff Light",
}; };
//let mut mdns = matter::mdns::bonjour::BonjourMdns::new().unwrap(); //let mut mdns = matter::mdns::astro::AstroMdns::new().unwrap();
let mut mdns = matter::mdns::libmdns::LibMdns::new().unwrap(); let mut mdns = matter::mdns::libmdns::LibMdns::new().unwrap();
let matter = Matter::new_default(&dev_info, &mut mdns); let matter = Matter::new_default(&dev_info, &mut mdns);
@ -80,10 +80,7 @@ fn main() {
let (len, addr) = udp.recv(&mut rx_buf).await.unwrap(); let (len, addr) = udp.recv(&mut rx_buf).await.unwrap();
let mut rx = Packet::new_rx(&mut rx_buf[..len]); let mut completion = transport.recv(addr, &mut rx_buf[..len], &mut tx_buf);
let mut tx = Packet::new_tx(&mut tx_buf);
let mut completion = transport.recv(addr, &mut rx, &mut tx);
while let Some(action) = completion.next_action().unwrap() { while let Some(action) = completion.next_action().unwrap() {
match action { match action {
@ -109,8 +106,8 @@ fn main() {
InteractionModel(DataModel::new(matter.borrow(), &node, &mut handler)); InteractionModel(DataModel::new(matter.borrow(), &node, &mut handler));
if im.handle(&mut ctx).unwrap() { if im.handle(&mut ctx).unwrap() {
if let Some(addr) = ctx.send().unwrap() { if ctx.send().unwrap() {
udp.send(addr, ctx.tx.as_slice()).await.unwrap(); udp.send(ctx.tx.peer, ctx.tx.as_slice()).await.unwrap();
} }
} }
} }

View file

@ -15,11 +15,10 @@ name = "matter"
path = "src/lib.rs" path = "src/lib.rs"
[features] [features]
default = ["std", "crypto_mbedtls", "nightly"] default = ["std", "crypto_mbedtls"]
std = ["alloc", "env_logger", "chrono", "rand", "qrcode", "libmdns", "simple-mdns", "simple-dns", "smol"] std = ["alloc", "env_logger", "chrono", "rand", "qrcode", "libmdns", "simple-mdns", "simple-dns", "smol"]
alloc = [] alloc = []
nightly = [] nightly = []
bonjour = ["astro-dnssd"]
crypto_openssl = ["openssl", "foreign-types", "hmac", "sha2"] crypto_openssl = ["openssl", "foreign-types", "hmac", "sha2"]
crypto_mbedtls = ["mbedtls", "alloc"] crypto_mbedtls = ["mbedtls", "alloc"]
crypto_esp_mbedtls = ["esp-idf-sys"] crypto_esp_mbedtls = ["esp-idf-sys"]
@ -48,7 +47,8 @@ qrcode = { version = "0.12", default-features = false, optional = true } # Print
libmdns = { version = "0.7", optional = true } libmdns = { version = "0.7", optional = true }
simple-mdns = { version = "0.4", features = ["sync"], optional = true } simple-mdns = { version = "0.4", features = ["sync"], optional = true }
simple-dns = { version = "0.5", optional = true } simple-dns = { version = "0.5", optional = true }
astro-dnssd = { version = "0.3", optional = true } astro-dnssd = { version = "0.3", optional = true } # On Linux needs avahi-compat-libdns_sd, i.e. on Ubuntu/Debian do `sudo apt-get install libavahi-compat-libdnssd-dev`
zeroconf = { version = "0.10", optional = true }
smol = { version = "1.3.0", optional = true} smol = { version = "1.3.0", optional = true}
# crypto # crypto

View file

@ -23,13 +23,15 @@ pub trait Mdns {
fn add( fn add(
&mut self, &mut self,
name: &str, name: &str,
service_type: &str, service: &str,
protocol: &str,
port: u16, port: u16,
service_subtypes: &[&str], service_subtypes: &[&str],
txt_kvs: &[(&str, &str)], txt_kvs: &[(&str, &str)],
) -> Result<(), Error>; ) -> Result<(), Error>;
fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error>; fn remove(&mut self, name: &str, service: &str, protocol: &str, port: u16)
-> Result<(), Error>;
} }
impl<T> Mdns for &mut T impl<T> Mdns for &mut T
@ -39,16 +41,23 @@ where
fn add( fn add(
&mut self, &mut self,
name: &str, name: &str,
service_type: &str, service: &str,
protocol: &str,
port: u16, port: u16,
service_subtypes: &[&str], service_subtypes: &[&str],
txt_kvs: &[(&str, &str)], txt_kvs: &[(&str, &str)],
) -> Result<(), Error> { ) -> Result<(), Error> {
(**self).add(name, service_type, port, service_subtypes, txt_kvs) (**self).add(name, service, protocol, port, service_subtypes, txt_kvs)
} }
fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> { fn remove(
(**self).remove(name, service_type, port) &mut self,
name: &str,
service: &str,
protocol: &str,
port: u16,
) -> Result<(), Error> {
(**self).remove(name, service, protocol, port)
} }
} }
@ -58,7 +67,8 @@ impl Mdns for DummyMdns {
fn add( fn add(
&mut self, &mut self,
_name: &str, _name: &str,
_service_type: &str, _service: &str,
_protocol: &str,
_port: u16, _port: u16,
_service_subtypes: &[&str], _service_subtypes: &[&str],
_txt_kvs: &[(&str, &str)], _txt_kvs: &[(&str, &str)],
@ -66,7 +76,13 @@ impl Mdns for DummyMdns {
Ok(()) Ok(())
} }
fn remove(&mut self, _name: &str, _service_type: &str, _port: u16) -> Result<(), Error> { fn remove(
&mut self,
_name: &str,
_service: &str,
_protocol: &str,
_port: u16,
) -> Result<(), Error> {
Ok(()) Ok(())
} }
} }
@ -117,7 +133,7 @@ impl<'a> MdnsMgr<'a> {
match mode { match mode {
ServiceMode::Commissioned => { ServiceMode::Commissioned => {
self.mdns self.mdns
.add(name, "_matter._tcp", self.matter_port, &[], &[]) .add(name, "_matter", "_tcp", self.matter_port, &[], &[])
} }
ServiceMode::Commissionable(discriminator) => { ServiceMode::Commissionable(discriminator) => {
let discriminator_str = Self::get_discriminator_str(discriminator); let discriminator_str = Self::get_discriminator_str(discriminator);
@ -136,7 +152,8 @@ impl<'a> MdnsMgr<'a> {
self.mdns.add( self.mdns.add(
name, name,
"_matter._udp", "_matterc",
"_udp",
self.matter_port, self.matter_port,
&[ &[
&self.get_long_service_subtype(discriminator), &self.get_long_service_subtype(discriminator),
@ -150,9 +167,11 @@ impl<'a> MdnsMgr<'a> {
pub fn unpublish_service(&mut self, name: &str, mode: ServiceMode) -> Result<(), Error> { pub fn unpublish_service(&mut self, name: &str, mode: ServiceMode) -> Result<(), Error> {
match mode { match mode {
ServiceMode::Commissioned => self.mdns.remove(name, "_matter._tcp", self.matter_port), ServiceMode::Commissioned => {
self.mdns.remove(name, "_matter", "_tcp", self.matter_port)
}
ServiceMode::Commissionable(_) => { ServiceMode::Commissionable(_) => {
self.mdns.remove(name, "_matter._udp", self.matter_port) self.mdns.remove(name, "_matterc", "_udp", self.matter_port)
} }
} }
} }
@ -193,8 +212,8 @@ impl<'a> MdnsMgr<'a> {
} }
} }
#[cfg(all(feature = "std", feature = "bonjour"))] #[cfg(all(feature = "std", feature = "astro-dnssd"))]
pub mod bonjour { pub mod astro {
use std::collections::HashMap; use std::collections::HashMap;
use super::Mdns; use super::Mdns;
@ -205,15 +224,16 @@ pub mod bonjour {
#[derive(Debug, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct ServiceId { pub struct ServiceId {
name: String, name: String,
service_type: String, service: String,
protocol: String,
port: u16, port: u16,
} }
pub struct BonjourMdns { pub struct AstroMdns {
services: HashMap<RegisteredDnsService, RegisteredDnsService>, services: HashMap<ServiceId, RegisteredDnsService>,
} }
impl BonjourMdns { impl AstroMdns {
pub fn new() -> Result<Self, Error> { pub fn new() -> Result<Self, Error> {
Ok(Self { Ok(Self {
services: HashMap::new(), services: HashMap::new(),
@ -223,56 +243,65 @@ pub mod bonjour {
pub fn add( pub fn add(
&mut self, &mut self,
name: &str, name: &str,
service_type: &str, service: &str,
protocol: &str,
port: u16, port: u16,
service_subtypes: &[&str], service_subtypes: &[&str],
txt_kvs: &[(&str, &str)], txt_kvs: &[(&str, &str)],
) -> Result<(), Error> { ) -> Result<(), Error> {
info!( info!(
"Registering mDNS service {}/{}/{}", "Registering mDNS service {}/{}.{} [{:?}]/{}",
name, service_type, port name, service, protocol, service_subtypes, port
); );
let _ = self.remove(name, service_type, port); let _ = self.remove(name, service, protocol, port);
let composite_service_type = if !service_subtypes.is_empty() { let composite_service_type = if !service_subtypes.is_empty() {
format!("{}{}", service_type, service_subtypes.join(",")) format!("{}.{},{}", service, protocol, service_subtypes.join(","))
} else { } else {
service_type format!("{}.{}", service, protocol)
}; };
let mut builder = DNSServiceBuilder::new(composite_service_type, port).with_name(name); let mut builder = DNSServiceBuilder::new(&composite_service_type, port).with_name(name);
for kvs in txt_kvs { for kvs in txt_kvs {
info!("mDNS TXT key {} val {}", kvs.0, kvs.1); info!("mDNS TXT key {} val {}", kvs.0, kvs.1);
builder = builder.with_key_value(kvs.0.to_string(), kvs.1.to_string()); builder = builder.with_key_value(kvs.0.to_string(), kvs.1.to_string());
} }
let service = builder.register().map_err(|_| Error::MdnsError)?; let svc = builder.register().map_err(|_| Error::MdnsError)?;
self.services.insert( self.services.insert(
ServiceId { ServiceId {
name: name.into(), name: name.into(),
service_type: service_type.into(), service: service.into(),
protocol: protocol.into(),
port, port,
}, },
service, svc,
); );
Ok(()) Ok(())
} }
pub fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> { pub fn remove(
&mut self,
name: &str,
service: &str,
protocol: &str,
port: u16,
) -> Result<(), Error> {
let id = ServiceId { let id = ServiceId {
name: name.into(), name: name.into(),
service_type: service_type.into(), service: service.into(),
protocol: protocol.into(),
port, port,
}; };
if self.services.remove(&id).is_some() { if self.services.remove(&id).is_some() {
info!( info!(
"Deregistering mDNS service {}/{}/{}", "Deregistering mDNS service {}/{}.{}/{}",
name, service_type, port name, service, protocol, port
); );
} }
@ -280,24 +309,172 @@ pub mod bonjour {
} }
} }
impl Mdns for BonjourMdns { impl Mdns for AstroMdns {
fn add( fn add(
&mut self, &mut self,
name: &str, name: &str,
service_type: &str, service: &str,
protocol: &str,
port: u16, port: u16,
service_subtypes: &[&str], service_subtypes: &[&str],
txt_kvs: &[(&str, &str)], txt_kvs: &[(&str, &str)],
) -> Result<(), Error> { ) -> Result<(), Error> {
BonjourMdns::add(self, name, service_type, port, service_subtypes, txt_kvs) AstroMdns::add(
self,
name,
service,
protocol,
port,
service_subtypes,
txt_kvs,
)
} }
fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> { fn remove(
BonjourMdns::remove(self, name, service_type, port) &mut self,
name: &str,
service: &str,
protocol: &str,
port: u16,
) -> Result<(), Error> {
AstroMdns::remove(self, name, service, protocol, port)
} }
} }
} }
// TODO: Maybe future
// #[cfg(all(feature = "std", feature = "zeroconf"))]
// pub mod zeroconf {
// use std::collections::HashMap;
// use super::Mdns;
// use crate::error::Error;
// use log::info;
// use zeroconf::prelude::*;
// use zeroconf::{MdnsService, ServiceType, TxtRecord};
// #[derive(Debug, Clone, Eq, PartialEq, Hash)]
// pub struct ServiceId {
// name: String,
// service: String,
// protocol: String,
// port: u16,
// }
// pub struct ZeroconfMdns {
// services: HashMap<ServiceId, MdnsService>,
// }
// impl ZeroconfMdns {
// pub fn new() -> Result<Self, Error> {
// Ok(Self {
// services: HashMap::new(),
// })
// }
// pub fn add(
// &mut self,
// name: &str,
// service: &str,
// protocol: &str,
// port: u16,
// service_subtypes: &[&str],
// txt_kvs: &[(&str, &str)],
// ) -> Result<(), Error> {
// info!(
// "Registering mDNS service {}/{}.{} [{:?}]/{}",
// name, service, protocol, service_subtypes, port
// );
// let _ = self.remove(name, service, protocol, port);
// let mut svc = MdnsService::new(
// ServiceType::with_sub_types(service, protocol, service_subtypes.into()).unwrap(),
// port,
// );
// let mut txt = TxtRecord::new();
// for kvs in txt_kvs {
// info!("mDNS TXT key {} val {}", kvs.0, kvs.1);
// txt.insert(kvs.0, kvs.1);
// }
// svc.set_txt_record(txt);
// //let event_loop = svc.register().map_err(|_| Error::MdnsError)?;
// self.services.insert(
// ServiceId {
// name: name.into(),
// service: service.into(),
// protocol: protocol.into(),
// port,
// },
// svc,
// );
// Ok(())
// }
// pub fn remove(
// &mut self,
// name: &str,
// service: &str,
// protocol: &str,
// port: u16,
// ) -> Result<(), Error> {
// let id = ServiceId {
// name: name.into(),
// service: service.into(),
// protocol: protocol.into(),
// port,
// };
// if self.services.remove(&id).is_some() {
// info!(
// "Deregistering mDNS service {}.{}/{}/{}",
// name, service, protocol, port
// );
// }
// Ok(())
// }
// }
// impl Mdns for ZeroconfMdns {
// fn add(
// &mut self,
// name: &str,
// service: &str,
// protocol: &str,
// port: u16,
// service_subtypes: &[&str],
// txt_kvs: &[(&str, &str)],
// ) -> Result<(), Error> {
// ZeroconfMdns::add(
// self,
// name,
// service,
// protocol,
// port,
// service_subtypes,
// txt_kvs,
// )
// }
// fn remove(
// &mut self,
// name: &str,
// service: &str,
// protocol: &str,
// port: u16,
// ) -> Result<(), Error> {
// ZeroconfMdns::remove(self, name, service, protocol, port)
// }
// }
// }
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub mod libmdns { pub mod libmdns {
use super::Mdns; use super::Mdns;
@ -310,7 +487,8 @@ pub mod libmdns {
#[derive(Debug, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct ServiceId { pub struct ServiceId {
name: String, name: String,
service_type: String, service: String,
protocol: String,
port: u16, port: u16,
} }
@ -332,16 +510,17 @@ pub mod libmdns {
pub fn add( pub fn add(
&mut self, &mut self,
name: &str, name: &str,
service_type: &str, service: &str,
protocol: &str,
port: u16, port: u16,
txt_kvs: &[(&str, &str)], txt_kvs: &[(&str, &str)],
) -> Result<(), Error> { ) -> Result<(), Error> {
info!( info!(
"Registering mDNS service {}/{}/{}", "Registering mDNS service {}/{}.{}/{}",
name, service_type, port name, service, protocol, port
); );
let _ = self.remove(name, service_type, port); let _ = self.remove(name, service, protocol, port);
let mut properties = Vec::new(); let mut properties = Vec::new();
for kvs in txt_kvs { for kvs in txt_kvs {
@ -350,8 +529,8 @@ pub mod libmdns {
} }
let properties: Vec<&str> = properties.iter().map(|entry| entry.as_str()).collect(); let properties: Vec<&str> = properties.iter().map(|entry| entry.as_str()).collect();
let service = self.responder.register( let svc = self.responder.register(
service_type.to_owned(), format!("{}.{}", service, protocol),
name.to_owned(), name.to_owned(),
port, port,
&properties, &properties,
@ -360,26 +539,34 @@ pub mod libmdns {
self.services.insert( self.services.insert(
ServiceId { ServiceId {
name: name.into(), name: name.into(),
service_type: service_type.into(), service: service.into(),
protocol: protocol.into(),
port, port,
}, },
service, svc,
); );
Ok(()) Ok(())
} }
pub fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> { pub fn remove(
&mut self,
name: &str,
service: &str,
protocol: &str,
port: u16,
) -> Result<(), Error> {
let id = ServiceId { let id = ServiceId {
name: name.into(), name: name.into(),
service_type: service_type.into(), service: service.into(),
protocol: protocol.into(),
port, port,
}; };
if self.services.remove(&id).is_some() { if self.services.remove(&id).is_some() {
info!( info!(
"Deregistering mDNS service {}/{}/{}", "Deregistering mDNS service {}/{}.{}/{}",
name, service_type, port name, service, protocol, port
); );
} }
@ -391,20 +578,28 @@ pub mod libmdns {
fn add( fn add(
&mut self, &mut self,
name: &str, name: &str,
service_type: &str, service: &str,
protocol: &str,
port: u16, port: u16,
_service_subtypes: &[&str], _service_subtypes: &[&str],
txt_kvs: &[(&str, &str)], txt_kvs: &[(&str, &str)],
) -> Result<(), Error> { ) -> Result<(), Error> {
LibMdns::add(self, name, service_type, port, txt_kvs) LibMdns::add(self, name, service, protocol, port, txt_kvs)
} }
fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> { fn remove(
LibMdns::remove(self, name, service_type, port) &mut self,
name: &str,
service: &str,
protocol: &str,
port: u16,
) -> Result<(), Error> {
LibMdns::remove(self, name, service, protocol, port)
} }
} }
} }
// TODO: Maybe future
// #[cfg(feature = "std")] // #[cfg(feature = "std")]
// pub mod simplemdns { // pub mod simplemdns {
// use std::net::Ipv4Addr; // use std::net::Ipv4Addr;

View file

@ -31,10 +31,7 @@ use crate::utils::rand::Rand;
use heapless::LinearMap; use heapless::LinearMap;
use super::session::CloneData; use super::session::CloneData;
use super::{ use super::{mrp::ReliableMessage, packet::Packet, session::SessionHandle, session::SessionMgr};
mrp::ReliableMessage, network::Address, packet::Packet, session::SessionHandle,
session::SessionMgr,
};
pub struct ExchangeCtx<'a> { pub struct ExchangeCtx<'a> {
pub exch: &'a mut Exchange, pub exch: &'a mut Exchange,
@ -43,7 +40,7 @@ pub struct ExchangeCtx<'a> {
} }
impl<'a> ExchangeCtx<'a> { impl<'a> ExchangeCtx<'a> {
pub fn send(&mut self, tx: &mut Packet) -> Result<Option<Address>, Error> { pub fn send(&mut self, tx: &mut Packet) -> Result<bool, Error> {
self.exch.send(tx, &mut self.sess) self.exch.send(tx, &mut self.sess)
} }
} }
@ -201,10 +198,10 @@ impl Exchange {
&mut self, &mut self,
tx: &mut Packet, tx: &mut Packet,
session: &mut SessionHandle, session: &mut SessionHandle,
) -> Result<Option<Address>, Error> { ) -> Result<bool, Error> {
if self.state == State::Terminate { if self.state == State::Terminate {
info!("Skipping tx for terminated exchange {}", self.id); info!("Skipping tx for terminated exchange {}", self.id);
return Ok(None); return Ok(false);
} }
trace!("payload: {:x?}", tx.as_mut_slice()); trace!("payload: {:x?}", tx.as_mut_slice());
@ -224,7 +221,7 @@ impl Exchange {
self.mrp.pre_send(tx)?; self.mrp.pre_send(tx)?;
session.send(tx)?; session.send(tx)?;
Ok(Some(session.get_peer_addr())) Ok(true)
} }
} }
@ -359,13 +356,11 @@ impl ExchangeMgr {
} }
} }
pub fn send(&mut self, exch_id: u16, tx: &mut Packet) -> Result<Address, Error> { pub fn send(&mut self, exch_id: u16, tx: &mut Packet) -> Result<bool, Error> {
let exchange = let exchange =
ExchangeMgr::_get_with_id(&mut self.exchanges, exch_id).ok_or(Error::NoExchange)?; ExchangeMgr::_get_with_id(&mut self.exchanges, exch_id).ok_or(Error::NoExchange)?;
let mut session = self.sess_mgr.get_session_handle(exchange.sess_idx); let mut session = self.sess_mgr.get_session_handle(exchange.sess_idx);
exchange.send(tx, &mut session)?; exchange.send(tx, &mut session)
Ok(session.get_peer_addr())
} }
pub fn purge(&mut self) { pub fn purge(&mut self) {
@ -388,7 +383,7 @@ impl ExchangeMgr {
.map(|(exch_id, _)| *exch_id) .map(|(exch_id, _)| *exch_id)
} }
pub fn evict_session(&mut self, tx: &mut Packet) -> Result<Option<Address>, Error> { pub fn evict_session(&mut self, tx: &mut Packet) -> Result<bool, Error> {
if let Some(index) = self.sess_mgr.get_session_for_eviction() { if let Some(index) = self.sess_mgr.get_session_for_eviction() {
info!("Sessions full, vacating session with index: {}", index); info!("Sessions full, vacating session with index: {}", index);
// If we enter here, we have an LRU session that needs to be reclaimed // If we enter here, we have an LRU session that needs to be reclaimed
@ -431,13 +426,11 @@ impl ExchangeMgr {
self.exchanges.remove(&exch_id); self.exchanges.remove(&exch_id);
} }
let addr = session.get_peer_addr();
self.sess_mgr.remove(index); self.sess_mgr.remove(index);
Ok(Some(addr)) Ok(true)
} else { } else {
Ok(None) Ok(false)
} }
} }
@ -571,7 +564,7 @@ mod tests {
let mut buf = [0; MAX_TX_BUF_SIZE]; let mut buf = [0; MAX_TX_BUF_SIZE];
let tx = &mut Packet::new_tx(&mut buf); let tx = &mut Packet::new_tx(&mut buf);
let evicted = mgr.evict_session(tx).unwrap(); let evicted = mgr.evict_session(tx).unwrap();
assert!(evicted.is_some()); assert!(evicted);
let session = mgr let session = mgr
.add_session(&get_clone_data(new_peer_sess_id, new_local_sess_id)) .add_session(&get_clone_data(new_peer_sess_id, new_local_sess_id))

View file

@ -28,11 +28,10 @@ use crate::secure_channel::pake::PaseMgr;
use crate::secure_channel::common::PROTO_ID_SECURE_CHANNEL; use crate::secure_channel::common::PROTO_ID_SECURE_CHANNEL;
use crate::secure_channel::core::SecureChannel; use crate::secure_channel::core::SecureChannel;
use crate::transport::mrp::ReliableMessage; use crate::transport::mrp::ReliableMessage;
use crate::transport::{exchange, packet::Packet}; use crate::transport::{exchange, network::Address, packet::Packet};
use crate::utils::epoch::{Epoch, UtcCalendar}; use crate::utils::epoch::{Epoch, UtcCalendar};
use crate::utils::rand::Rand; use crate::utils::rand::Rand;
use super::network::Address;
use super::proto_ctx::ProtoCtx; use super::proto_ctx::ProtoCtx;
use super::session::CloneData; use super::session::CloneData;
@ -52,9 +51,8 @@ pub enum RecvAction<'r, 'p> {
pub struct RecvCompletion<'r, 'a, 'p> { pub struct RecvCompletion<'r, 'a, 'p> {
mgr: &'r mut TransportMgr<'a>, mgr: &'r mut TransportMgr<'a>,
addr: Address, // TODO: Not used yet rx: Packet<'p>,
rx: &'r mut Packet<'p>, tx: Packet<'p>,
tx: &'r mut Packet<'p>,
state: RecvState, state: RecvState,
} }
@ -73,91 +71,94 @@ impl<'r, 'a, 'p> RecvCompletion<'r, 'a, 'p> {
fn maybe_next_action(&mut self) -> Result<Option<Option<RecvAction<'_, 'p>>>, Error> { fn maybe_next_action(&mut self) -> Result<Option<Option<RecvAction<'_, 'p>>>, Error> {
self.mgr.exch_mgr.purge(); self.mgr.exch_mgr.purge();
match core::mem::replace(&mut self.state, RecvState::New) { let (state, next) = match core::mem::replace(&mut self.state, RecvState::New) {
RecvState::New => { RecvState::New => {
self.mgr.exch_mgr.get_sess_mgr().decode(self.rx)?; self.mgr.exch_mgr.get_sess_mgr().decode(&mut self.rx)?;
self.state = RecvState::OpenExchange; (RecvState::OpenExchange, None)
Ok(None)
} }
RecvState::OpenExchange => match self.mgr.exch_mgr.recv(self.rx) { RecvState::OpenExchange => match self.mgr.exch_mgr.recv(&mut self.rx) {
Ok(Some(exch_ctx)) => { Ok(Some(exch_ctx)) => {
if self.rx.get_proto_id() == PROTO_ID_SECURE_CHANNEL { if self.rx.get_proto_id() == PROTO_ID_SECURE_CHANNEL {
let mut proto_ctx = ProtoCtx::new(exch_ctx, self.rx, self.tx); let mut proto_ctx = ProtoCtx::new(exch_ctx, &self.rx, &mut self.tx);
let (reply, clone_data) = self.mgr.secure_channel.handle(&mut proto_ctx)?; let (reply, clone_data) = self.mgr.secure_channel.handle(&mut proto_ctx)?;
if let Some(clone_data) = clone_data { let state = if let Some(clone_data) = clone_data {
self.state = RecvState::AddSession(clone_data); RecvState::AddSession(clone_data)
} else { } else {
self.state = RecvState::Ack; RecvState::Ack
} };
let addr = if reply { proto_ctx.send()? } else { None }; if reply {
if proto_ctx.send()? {
if let Some(addr) = addr { (
Ok(Some(Some(RecvAction::Send(addr, self.tx.as_slice())))) state,
Some(Some(RecvAction::Send(self.tx.peer, self.tx.as_slice()))),
)
} else {
(state, None)
}
} else { } else {
Ok(None) (state, None)
} }
} else { } else {
let proto_ctx = ProtoCtx::new(exch_ctx, self.rx, self.tx); let proto_ctx = ProtoCtx::new(exch_ctx, &self.rx, &mut self.tx);
self.state = RecvState::Ack;
Ok(Some(Some(RecvAction::Interact(proto_ctx)))) (RecvState::Ack, Some(Some(RecvAction::Interact(proto_ctx))))
} }
} }
Ok(None) => { Ok(None) => (RecvState::Ack, None),
self.state = RecvState::Ack; Err(Error::Duplicate) => (RecvState::Ack, Some(None)),
Ok(None) Err(Error::NoSpace) => (RecvState::EvictSession, None),
} Err(err) => Err(err)?,
Err(Error::NoSpace) => {
self.state = RecvState::EvictSession;
Ok(None)
}
Err(err) => Err(err),
}, },
RecvState::AddSession(clone_data) => match self.mgr.exch_mgr.add_session(&clone_data) { RecvState::AddSession(clone_data) => match self.mgr.exch_mgr.add_session(&clone_data) {
Ok(_) => { Ok(_) => (RecvState::Ack, None),
self.state = RecvState::Ack; Err(Error::NoSpace) => (RecvState::EvictSession2(clone_data), None),
Ok(None) Err(err) => Err(err)?,
}
Err(Error::NoSpace) => {
self.state = RecvState::EvictSession2(clone_data);
Ok(None)
}
Err(err) => Err(err),
}, },
RecvState::EvictSession => { RecvState::EvictSession => {
let addr = self.mgr.exch_mgr.evict_session(self.tx)?; if self.mgr.exch_mgr.evict_session(&mut self.tx)? {
self.state = RecvState::OpenExchange; (
if let Some(addr) = addr { RecvState::OpenExchange,
Ok(Some(Some(RecvAction::Send(addr, self.tx.as_slice())))) Some(Some(RecvAction::Send(self.tx.peer, self.tx.as_slice()))),
)
} else { } else {
Ok(None) (RecvState::EvictSession, None)
} }
} }
RecvState::EvictSession2(clone_data) => { RecvState::EvictSession2(clone_data) => {
let addr = self.mgr.exch_mgr.evict_session(self.tx)?; if self.mgr.exch_mgr.evict_session(&mut self.tx)? {
self.state = RecvState::AddSession(clone_data); (
if let Some(addr) = addr { RecvState::AddSession(clone_data),
Ok(Some(Some(RecvAction::Send(addr, self.tx.as_slice())))) Some(Some(RecvAction::Send(self.tx.peer, self.tx.as_slice()))),
)
} else { } else {
Ok(None) (RecvState::EvictSession2(clone_data), None)
} }
} }
RecvState::Ack => { RecvState::Ack => {
if let Some(exch_id) = self.mgr.exch_mgr.pending_ack() { if let Some(exch_id) = self.mgr.exch_mgr.pending_ack() {
info!("Sending MRP Standalone ACK for exch {}", exch_id); info!("Sending MRP Standalone ACK for exch {}", exch_id);
ReliableMessage::prepare_ack(exch_id, self.tx); ReliableMessage::prepare_ack(exch_id, &mut self.tx);
let addr = self.mgr.exch_mgr.send(exch_id, self.tx)?; if self.mgr.exch_mgr.send(exch_id, &mut self.tx)? {
Ok(Some(Some(RecvAction::Send(addr, self.tx.as_slice())))) (
RecvState::Ack,
Some(Some(RecvAction::Send(self.tx.peer, self.tx.as_slice()))),
)
} else {
(RecvState::Ack, None)
}
} else { } else {
Ok(Some(None)) (RecvState::Ack, Some(None))
} }
} }
} };
self.state = state;
Ok(next)
} }
} }
@ -232,12 +233,16 @@ impl<'a> TransportMgr<'a> {
pub fn recv<'r, 'p>( pub fn recv<'r, 'p>(
&'r mut self, &'r mut self,
addr: Address, addr: Address,
rx: &'r mut Packet<'p>, rx_buf: &'p mut [u8],
tx: &'r mut Packet<'p>, tx_buf: &'p mut [u8],
) -> RecvCompletion<'r, 'a, 'p> { ) -> RecvCompletion<'r, 'a, 'p> {
let mut rx = Packet::new_rx(rx_buf);
let tx = Packet::new_tx(tx_buf);
rx.peer = addr;
RecvCompletion { RecvCompletion {
mgr: self, mgr: self,
addr,
rx, rx,
tx, tx,
state: RecvState::New, state: RecvState::New,

View file

@ -18,7 +18,6 @@
use crate::error::Error; use crate::error::Error;
use super::exchange::ExchangeCtx; use super::exchange::ExchangeCtx;
use super::network::Address;
use super::packet::Packet; use super::packet::Packet;
/// This is the context in which a receive packet is being processed /// This is the context in which a receive packet is being processed
@ -36,7 +35,7 @@ impl<'a, 'b> ProtoCtx<'a, 'b> {
Self { exch_ctx, rx, tx } Self { exch_ctx, rx, tx }
} }
pub fn send(&mut self) -> Result<Option<Address>, Error> { pub fn send(&mut self) -> Result<bool, Error> {
self.exch_ctx.exch.send(self.tx, &mut self.exch_ctx.sess) self.exch_ctx.exch.send(self.tx, &mut self.exch_ctx.sess)
} }
} }

View file

@ -56,7 +56,7 @@ impl UdpListener {
Error::Network Error::Network
})?; })?;
info!("Got packet: {:?} from addr {:?}", in_buf, addr); info!("Got packet: {:?} from addr {:?}", &in_buf[..size], addr);
Ok((size, Address::Udp(addr))) Ok((size, Address::Udp(addr)))
} }