diff --git a/src/ironforce.rs b/src/ironforce.rs index 155ccf6..3f29ed9 100644 --- a/src/ironforce.rs +++ b/src/ironforce.rs @@ -1,18 +1,24 @@ use crate::transport::Transport; use crate::crypto::{PublicKey, Keys}; use crate::message::{Message, MsgType}; +use crate::tunnel::Tunnel; use alloc::vec::Vec; +const UNICAST_TUNNELS: u32 = 2; +const MULTICAST_TUNNELS: u32 = 5; + + pub struct IronForce { transport: Transport, + tunnels: Vec, key_pack: Keys, } impl IronForce { pub fn new() -> IronForce { - IronForce { transport: Transport::new(), key_pack: Keys::gen() } + IronForce { transport: Transport::new(), tunnels: Vec::::new(), key_pack: Keys::gen() } } fn is_valid_message(&self, msg: &Message) -> bool { @@ -24,16 +30,43 @@ impl IronForce { Message::new(msg_type, body.clone(), &self.key_pack) } + fn send_through_tunnel_to(&self, msg: &Message, tunnel: &Tunnel, to: &PublicKey) { + self.transport.send_to(msg, &tunnel.next(&self.key_pack.get_public(), &to).unwrap()); + } + fn service_msg(&self, body: &Vec) { - self.transport.send(&self.new_message(MsgType::Service, body)) + self.transport.send_service(&self.new_message(MsgType::Service, body)) } - pub fn multicast(&self, body: &Vec) { - self.transport.send(&self.new_message(MsgType::MultiCast, body)) + pub fn multicast(&self, msg: &Message) -> u32 { + let mut count = 0; + for tunnel in &self.tunnels { + for node in tunnel.next_nodes(&self.key_pack.get_public()) { + count += 1; + self.send_through_tunnel_to(msg, tunnel, &node) + } + if count == MULTICAST_TUNNELS { + break; + } + } + count } - pub fn send_message_to(&self, to: PublicKey, body: &Vec) { - self.transport.send(&self.new_message(MsgType::UniCast(to), body)) + pub fn send_message_to(&self, msg: &Message, to: PublicKey) -> u32 { + let mut count = 0; + for tunnel in &self.tunnels { + if tunnel.is_in_tunnel(&to) { + count += 1; + self.send_through_tunnel_to(msg, tunnel, &to) + } + if count == UNICAST_TUNNELS { + break; + } + } + if count == 0 { + // todo: send service message and create new tunnel + } + count } fn handle_message(&self, msg: &Message) { @@ -41,10 +74,10 @@ impl IronForce { match &msg.content.msg_type { MsgType::Service => { self.service_msg(&msg.content.body) - }, + } MsgType::MultiCast => { // todo - }, + } MsgType::UniCast(target) => { // todo } diff --git a/src/transport.rs b/src/transport.rs index 5e2d999..9e167c1 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -1,14 +1,17 @@ use crate::message::Message; -#[cfg(not(feature = "std"))] use crate::message::MsgType; +#[cfg(not(feature = "std"))] +use crate::message::MsgType; use crate::crypto::PublicKey; -#[cfg(feature = "std")] use crate::way::Way; +#[cfg(feature = "std")] +use crate::way::Way; #[cfg(feature = "std")] use std::thread; #[cfg(feature = "std")] use std::sync::{Arc, Mutex}; use alloc::vec::Vec; -#[cfg(feature = "std")] use alloc::boxed::Box; +#[cfg(feature = "std")] +use alloc::boxed::Box; #[cfg(not(feature = "std"))] @@ -35,6 +38,14 @@ impl Transport { Vec::::new(), &crate::crypto::Keys::gen()), PublicKey { key: [0u8; 32] }) } + + pub fn send_service(&self, msg: &Message) { + + } + + pub fn send_to(&self, msg: &Message, to: &PublicKey) { + + } } #[cfg(feature = "std")] @@ -44,12 +55,18 @@ impl Transport { transport } - pub fn send(&self, msg: &Message) { - for way in &self.ways { + pub fn send_service(&self, msg: &Message) { + for way in &self.ways { // todo: do it in threads way.send(&msg); } } + pub fn send_to(&self, msg: &Message, to: &PublicKey) { + for way in &self.ways { + way.send_to(&msg, to); + } + } + pub fn receive(&mut self) -> (Message, PublicKey) { if self.msg_pool.len() != 0 { let msg = self.msg_pool[0].clone(); diff --git a/src/tunnel.rs b/src/tunnel.rs index 63dbf3a..8f65242 100644 --- a/src/tunnel.rs +++ b/src/tunnel.rs @@ -60,4 +60,15 @@ impl Tunnel { Option::from(self.nodes[my_index + 1].clone()) }; } + + pub fn next_nodes(&self, me: &PublicKey) -> Vec { + let my_index = self.nodes + .iter() + .enumerate() + .find(|&node| node.1 == me).unwrap().0; + let mut result = Vec::::new(); + if my_index > 0 { result.push(self.nodes[my_index - 1].clone()) }; + if my_index < self.nodes.len() - 1 { result.push(self.nodes[my_index + 1].clone()) }; + result + } } diff --git a/src/way.rs b/src/way.rs index 4eb18da..01ebe0e 100644 --- a/src/way.rs +++ b/src/way.rs @@ -3,5 +3,6 @@ use crate::crypto::PublicKey; pub trait Way { fn send(&self, msg: &Message); + fn send_to(&self, msg: &Message, to: &PublicKey); fn receive(&self) -> (Message, PublicKey); }