diff --git a/README.md b/README.md index 747f2c7..bec9d83 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,25 @@ +# Ironforce + Degeon + +IronForce is a peer-to-peer decentralized network, Degeon is a messenger built on it. + +![](images/logo.png) + # Ironforce -IronForce is a decentralized network +The Ironforce network: + +- Has messages encrypted and signed using RSA + +- Can build efficient tunnels between two nodes + +- Is anonymous: it's very hard to create a connection between a node's IP and its public key + +- Can be extended to support any interface, like Bluetooth or even radio + +- Can run on ARM microcontrollers + +![](images/scheme.png) + +# Degeon + +Degeon is just a messenger built on IronForce to show its abilities. \ No newline at end of file diff --git a/degeon/src/message.rs b/degeon/src/message.rs index a840a17..2df5a0f 100644 --- a/degeon/src/message.rs +++ b/degeon/src/message.rs @@ -12,5 +12,4 @@ pub enum ServiceMsg { NameRequest, NameStatement(String), Ping, - HiThere, } diff --git a/degeon/src/state.rs b/degeon/src/state.rs index b245292..6a01786 100644 --- a/degeon/src/state.rs +++ b/degeon/src/state.rs @@ -3,11 +3,12 @@ use crate::message::{DegMessage, ServiceMsg}; use core::default::Default; use futures::Stream; use iced::{ - button, Align, Application, Button, Column, Element, HorizontalAlignment, Length, Row, - Text, TextInput, VerticalAlignment, + button, Align, Application, Button, Column, Element, HorizontalAlignment, Length, Row, Text, + TextInput, VerticalAlignment, }; use ironforce::res::{IFError, IFResult}; use ironforce::{IronForce, Keys, Message, MessageType, PublicKey}; +use std::hash::Hash; use std::pin::Pin; use std::sync::{Arc, Mutex}; use std::task::{Context, Poll}; @@ -223,7 +224,10 @@ impl Degeon { pub fn process_message(&self, msg: ironforce::Message) -> IFResult> { let deg_msg: DegMessage = - serde_json::from_slice(msg.get_decrypted(&self.keys)?.as_slice())?; + match serde_json::from_slice(msg.get_decrypted(&self.keys)?.as_slice()) { + Ok(r) => r, + Err(_) => return Ok(None) + }; let sender = msg.get_sender(&self.keys).unwrap(); Ok(match °_msg { DegMessage::Text(_) | DegMessage::File(_) => { @@ -240,9 +244,8 @@ impl Degeon { Some(GuiEvent::SetName(sender, name.to_string())) } ServiceMsg::Ping => self - .send_message(DegMessage::Service(ServiceMsg::HiThere), &sender) + .send_message(DegMessage::Service(ServiceMsg::NameStatement(self.my_name.clone())), &sender) .map(|_| None)?, - ServiceMsg::HiThere => Some(GuiEvent::NewChat(sender)), }, }) } @@ -258,21 +261,21 @@ impl Degeon { } pub fn send_message(&self, msg: DegMessage, target: &PublicKey) -> IFResult<()> { - if self.ironforce.lock().unwrap().get_tunnel(target).is_none() { - println!("Creating a tunnel"); - self.ironforce - .lock() - .unwrap() - .initialize_tunnel_creation(target)?; - let mut counter = 0; - while self.ironforce.lock().unwrap().get_tunnel(target).is_none() { - std::thread::sleep(std::time::Duration::from_millis(350)); - counter += 1; - if counter > 100 { - return Err(IFError::TunnelNotFound); - } - } - } + // if self.ironforce.lock().unwrap().get_tunnel(target).is_none() { + // println!("Creating a tunnel"); + // self.ironforce + // .lock() + // .unwrap() + // .initialize_tunnel_creation(target)?; + // let mut counter = 0; + // while self.ironforce.lock().unwrap().get_tunnel(target).is_none() { + // std::thread::sleep(std::time::Duration::from_millis(350)); + // counter += 1; + // if counter > 100 { + // return Err(IFError::TunnelNotFound); + // } + // } + // } self.ironforce.lock().unwrap().send_to_all( Message::build() .message_type(MessageType::Broadcast) @@ -290,9 +293,12 @@ impl Stream for Degeon { fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { println!("Degeon worker is being polled"); let msg = self.ironforce.lock().unwrap().read_message(); + println!("Msg: {:?}", msg); match msg.map(|msg| self.process_message(msg).unwrap()) { None | Some(None) => Poll::Pending, - Some(Some(msg)) => Poll::Ready(Some(msg)), + Some(Some(msg)) => { + Poll::Ready(Some(msg)) + } } } } @@ -308,6 +314,13 @@ where std::any::TypeId::of::().hash(state); self.ironforce.lock().unwrap().hash(state); + + // std::time::SystemTime::now().hash(state); + std::time::UNIX_EPOCH + .elapsed() + .unwrap() + .as_secs() + .hash(state); } fn stream( @@ -414,11 +427,7 @@ impl Application for State { .push((true, new_msg.clone())); let data_cloned = self.data.clone(); let target = self.data.chats[self.selected_chat].pkey.clone(); - std::thread::spawn(move || { - data_cloned - .send_message(new_msg, &target) - .unwrap() - }); + std::thread::spawn(move || data_cloned.send_message(new_msg, &target).unwrap()); } GuiEvent::NewChat(pkey) => { if self.data.chat_with(&pkey).is_none() { diff --git a/src/interfaces/ip.rs b/src/interfaces/ip.rs index be6aacc..3ffc440 100644 --- a/src/interfaces/ip.rs +++ b/src/interfaces/ip.rs @@ -177,7 +177,7 @@ impl Interface for IPInterface { message, }; self.package_queue - .push((package, format!("{:?}", connection.peer_addr()?))); + .insert(0, (package, format!("{:?}", connection.peer_addr()?))); } MessageType::PeersShared => { let peers: Vec = serde_cbor::from_slice(message.as_slice())?; diff --git a/src/ironforce.rs b/src/ironforce.rs index 0bed09a..15a3262 100644 --- a/src/ironforce.rs +++ b/src/ironforce.rs @@ -291,7 +291,7 @@ impl IronForce { MessageType::SingleCast if message.check_recipient(&self.keys) => { #[cfg(feature = "std")] println!("New message: {:?}", message.get_decrypted(&self.keys)); - self.messages.push(message.clone()) + self.messages.insert(0, message.clone()) } MessageType::SingleCast => { if let Some(tunnel) = self @@ -312,7 +312,7 @@ impl IronForce { #[cfg(feature = "std")] println!("New message: {:?}", message.get_decrypted(&self.keys)); if message.check_recipient(&self.keys) { - self.messages.push(message.clone()); + self.messages.insert(0, message.clone()); } self.send_to_all(message)?; }