Browse Source

Abstract functions in the `IF` struct

interface-2
Lev 3 years ago
parent
commit
a47c5e14ff
  1. 71
      src/ironforce.rs
  2. 1
      src/lib.rs
  3. 30
      src/message.rs
  4. 2
      src/res.rs
  5. 2
      src/transport.rs
  6. 28
      src/tunnel.rs

71
src/ironforce.rs

@ -1,5 +1,74 @@
use alloc::vec::Vec;
use alloc::vec;
use crate::crypto::PublicKey;
use crate::message::{Message, MessageType, ServiceMessageType};
use crate::res::{IFError, IFResult};
use crate::transport::Transport; use crate::transport::Transport;
use crate::tunnel::Tunnel;
/// Main worker
pub struct IronForce { pub struct IronForce {
transport: Transport /// the struct that manages communicating with neighbor nodes
transport: Transport,
/// Tunnels that are known to this node
tunnels: Vec<Tunnel>,
/// Additional modules that may be plugged in later,
/// for example internet access (like Tor)
/// and some kind of decentralized storage
additional_modules: Vec<()>,
/// Non-service messages to give outside
messages: Vec<Message>,
}
impl IronForce {
/// Create new worker
pub fn new() -> Self {
Self {
transport: Transport::new(crate::interfaces::get_interfaces()),
tunnels: vec![],
additional_modules: vec![],
messages: vec![],
}
}
/// Create a new tunnel to another node
fn create_new_tunnel(&mut self, _destination: PublicKey) -> IFResult<Tunnel> {
todo!()
}
/// Send a message through tunnel
fn send_through_tunnel(&mut self, _tunnel_id: u64, _message: Message, _direction: Option<bool>) -> IFResult<()> {
todo!()
}
/// Send a message to another node,
/// creating a new tunnel if needed
pub fn send_message(&mut self, message: Message, destination: PublicKey) -> IFResult<()> {
if let Some(Some(tunnel_id)) = self.tunnels.iter()
.find(|t| t.target_node.as_ref() == Some(&destination) || t.nodes_in_tunnel.as_ref().map(|nodes| nodes.contains(&destination)) == Some(true))
.map(|tunnel| tunnel.id) {
self.send_through_tunnel(tunnel_id, message, None)
} else {
Err(IFError::TunnelNotFound)
}
}
/// Process a message: if it's a service message, act accordingly.
/// Otherwise, add to `self.messages`
fn process_message(&mut self, message: Message) {
match message.message_type {
MessageType::Service(msg_type) => match msg_type {
ServiceMessageType::TunnelBuilding(_tunnel) => {
todo!()
}
}
MessageType::SingleCast | MessageType::Broadcast => { self.messages.push(message) }
}
}
/// Get a message from `self.messages`
pub fn read_message(&mut self) -> Option<Message> {
self.messages.pop()
}
} }

1
src/lib.rs

@ -4,6 +4,7 @@
extern crate alloc; extern crate alloc;
extern crate rand; extern crate rand;
extern crate rsa; extern crate rsa;
extern crate serde;
extern crate core_error; extern crate core_error;
mod crypto; mod crypto;

30
src/message.rs

@ -1,13 +1,16 @@
use alloc::string::String;
use alloc::vec::Vec; use alloc::vec::Vec;
use crate::crypto::{Keys, PublicKey}; use crate::crypto::{Keys, PublicKey};
use crate::res::IFResult; use crate::res::IFResult;
use crate::tunnel::TunnelPublic; use crate::tunnel::TunnelPublic;
use serde::{Serialize, Deserialize};
/// A serialized message /// A serialized message
pub(crate) type MessageBytes = Vec<u8>; pub(crate) type MessageBytes = Vec<u8>;
/// Signature of the message: optional and optionally encrypted sender's key and signed hash
#[derive(Serialize, Deserialize, Clone)]
pub enum Signature { pub enum Signature {
/// The message is signed. Author is unknown /// The message is signed. Author is unknown
NotSigned, NotSigned,
@ -20,19 +23,35 @@ pub enum Signature {
SignedPrivately { SignedPrivately {
sender_encrypted: Vec<u8>, sender_encrypted: Vec<u8>,
signature: Vec<u8>, signature: Vec<u8>,
},
}
/// Network name and version
#[derive(Serialize, Deserialize, Clone)]
struct NetworkInfo {
network_name: String,
version: String,
}
impl Default for NetworkInfo {
fn default() -> Self {
Self { version: String::from("0.1.0"), network_name: String::from("test") }
} }
} }
#[derive(Serialize, Deserialize, Clone)]
pub enum MessageType { pub enum MessageType {
SingleCast, SingleCast,
Broadcast, Broadcast,
Service(ServiceMessageType), Service(ServiceMessageType),
} }
#[derive(Serialize, Deserialize, Clone)]
pub enum ServiceMessageType { pub enum ServiceMessageType {
TunnelBuilding(TunnelPublic) TunnelBuilding(TunnelPublic)
} }
#[derive(Serialize, Deserialize, Clone)]
pub enum MessageContent { pub enum MessageContent {
/// Just plaintext message content /// Just plaintext message content
Plain(Vec<u8>), Plain(Vec<u8>),
@ -40,13 +59,14 @@ pub enum MessageContent {
Encrypted(Vec<u8>), Encrypted(Vec<u8>),
} }
#[derive(Serialize, Deserialize, Clone)]
pub struct Message { pub struct Message {
/// Content of the message (not to be confused with the bytes that we are sending through interfaces) /// Content of the message (not to be confused with the bytes that we are sending through interfaces)
content: MessageContent, pub content: MessageContent,
/// The type of this message /// The type of this message
message_type: MessageType, pub message_type: MessageType,
/// Sender's signature /// Sender's signature
signature: Signature, pub signature: Signature,
/// A random number that is used in hash together with the content /// A random number that is used in hash together with the content
salt: u64, salt: u64,
/// Hash of message content and the salt /// Hash of message content and the salt
@ -55,6 +75,8 @@ pub struct Message {
recipient_verification: Option<Vec<u8>>, recipient_verification: Option<Vec<u8>>,
/// ID of the tunnel that is used /// ID of the tunnel that is used
tunnel_id: u64, tunnel_id: u64,
/// Network info
network_info: NetworkInfo,
} }
impl Message { impl Message {

2
src/res.rs

@ -7,6 +7,8 @@ use core::fmt::Debug;
pub enum IFError { pub enum IFError {
/// An error that was created in some dependency and then converted to `IFError` /// An error that was created in some dependency and then converted to `IFError`
General(String), General(String),
/// A tunnel satisfying some conditions has not been found
TunnelNotFound,
} }

2
src/transport.rs

@ -134,7 +134,7 @@ impl Transport {
self.interfaces.par_iter_mut().map(|interface| interface.main_loop_iteration()).collect::<IFResult<_>>()?; self.interfaces.par_iter_mut().map(|interface| interface.main_loop_iteration()).collect::<IFResult<_>>()?;
#[cfg(not(std))] #[cfg(not(std))]
{ {
self.interfaces.iter_mut().map(|interface| if !interface.has_blocking_main() { interface.main_loop_iteration() } else { Ok(()) }).collect::<IFResult<_>>()?; self.interfaces.iter_mut().try_for_each(|interface| if !interface.has_blocking_main() { interface.main_loop_iteration() } else { Ok(()) })?;
let blocking_interface_index = self.interfaces.iter().position(|interface| interface.has_blocking_main()); let blocking_interface_index = self.interfaces.iter().position(|interface| interface.has_blocking_main());
if let Some(ind) = blocking_interface_index { if let Some(ind) = blocking_interface_index {
self.interfaces[ind].main_loop_iteration()?; self.interfaces[ind].main_loop_iteration()?;

28
src/tunnel.rs

@ -1,30 +1,36 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use crate::crypto::PublicKey; use crate::crypto::PublicKey;
use serde::{Serialize, Deserialize};
/// A tunnel that is used for communication /// A tunnel that is used for communication
#[derive(Serialize, Clone, Deserialize)]
pub struct Tunnel { pub struct Tunnel {
/// Tunnel's id /// Tunnel's id.
id: Option<u64>, /// By the way, this id is `None` until the tunnel is validated in the backward movement
/// Ids that are pub id: Option<u64>,
local_ids: Vec<u64>, /// Ids, each of them is just for local storage on each node until a final global id is created
pub local_ids: Vec<u64>,
/// Ids of peers (in transport) by which we can send a message - one for backward direction, another for forward /// Ids of peers (in transport) by which we can send a message - one for backward direction, another for forward
peer_ids: (u64, u64), pub peer_ids: (u64, u64),
/// Time at which this tunnel should be destroyed (UNIX epoch) /// Time at which this tunnel should be destroyed (UNIX epoch)
ttd: u64, pub ttd: u64,
/// Public keys of nodes /// Public keys of nodes in the tunnel
nodes_in_tunnel: Option<Vec<PublicKey>>, pub nodes_in_tunnel: Option<Vec<PublicKey>>,
/// Is this tunnel used for multicast? /// Is this tunnel used for multicast?
is_multicast: bool, pub is_multicast: bool,
/// If we created this tunnel, then this is the node that it's used to communicate with
pub target_node: Option<PublicKey>,
} }
/// Tunnel, but only the fields that are ok to share /// Tunnel, but only the fields that are ok to share
#[derive(Serialize, Clone, Deserialize)]
pub struct TunnelPublic { pub struct TunnelPublic {
/// Tunnel's id /// Tunnel's id
id: Option<u64>, id: Option<u64>,
/// Ids that are /// Ids, each of them is just for local storage on each node until a final global id is created
local_ids: Vec<u64>, local_ids: Vec<u64>,
/// Time at which this tunnel should be destroyed (UNIX epoch) /// Time at which this tunnel should be destroyed (UNIX epoch)
ttd: u64, ttd: u64,
/// Public keys of nodes /// Public keys of nodes in the tunnel
nodes_in_tunnel: Option<Vec<PublicKey>>, nodes_in_tunnel: Option<Vec<PublicKey>>,
} }

Loading…
Cancel
Save