// this class consists of a thread that will re send pings every time the first element // of the stack is at the correct unix time use std::{ collections::{HashMap, VecDeque}, net::{AddrParseError, Ipv4Addr, SocketAddr}, ops::Add, process::Command, sync::{Arc, Mutex}, thread, time::{self, Duration, SystemTime}, }; use crate::NetworkEvent; use crate::{ P2PSharedData, construct_message, generate_id, messages_structure, registration::perform_handshake, }; use crossbeam_channel::{Receiver, Sender}; use p256::ecdsa::VerifyingKey; #[derive(Debug, Clone)] pub struct PeerInfo { pub username: String, pub pubkey: VerifyingKey, pub ip: SocketAddr, } pub struct HandshakeHistory { //time_k_ip_v: HashMap, username_k_peerinfo_v: HashMap, ip_k_peerinfo_v: HashMap, } impl HandshakeHistory { pub fn new() -> HandshakeHistory { HandshakeHistory { //time_k_ip_v: HashMap::new(), //ip_k_peerinfo_v: HashMap::new(), username_k_peerinfo_v: HashMap::new(), ip_k_peerinfo_v: HashMap::new(), } } /*pub fn update_handshake(&self) { let hashmap_shared = Arc::new(self.username_k_peerinfo_v); thread::spawn(move || { let selfhashmap = hashmap_shared.clone(); loop { for peer in selfhashmap.keys() { let peer_ip = selfhashmap.get(peer); // send ping } let mut child = Command::new("sleep").arg("10").spawn().unwrap(); let _result = child.wait().unwrap(); } }); }*/ pub fn get_peer_info_username(&self, username: String) -> Option<&PeerInfo> { self.username_k_peerinfo_v.get(&username).clone() } pub fn get_peer_info_ip(&self, ip: String) -> Option<&PeerInfo> { self.ip_k_peerinfo_v.get(&ip).clone() } pub fn update_handshake(&self) { // clone the map so we own it (cheap if PeerInfo is Clone) let map_clone: Arc> = Arc::new(self.username_k_peerinfo_v.clone()); //let map_ip_clone: Arc> = Arc::new(self.ip_k_peerinfo_v.clone()); let map_for_thread = Arc::clone(&map_clone); thread::spawn(move || { loop { // Arc> derefs to &HashMap so these reads work for (peer, peerinfo) in map_for_thread.iter() { // send ping to peerinfo } thread::sleep(Duration::from_secs(10)); } }); } pub fn update_peer_info(&mut self, ip: String, username: String) { let peerinfo = self.get_peer_info_ip(ip.clone()); match peerinfo { Some(peer_info) => match ip.parse::() { Ok(addr) => { let new_peer_info = PeerInfo { username: username.clone(), pubkey: peer_info.pubkey, ip: addr, }; self.ip_k_peerinfo_v.insert(ip, new_peer_info.clone()); self.username_k_peerinfo_v.insert(username, new_peer_info); } Err(e) => eprintln!("parse error: {}", e), }, None => { eprintln!("no peer info found in hashmap") } } } pub fn add_new_handshake(&mut self, hash: VerifyingKey, username: String, ip: SocketAddr) { let peerinfo = PeerInfo { username: username.clone(), pubkey: hash, ip, }; self.username_k_peerinfo_v .insert(username, peerinfo.clone()); self.ip_k_peerinfo_v .insert(ip.to_string(), peerinfo.clone()); } } pub fn perform_discover( username: String, hash: String, sd: &P2PSharedData, server_ip: String, event_tx: Sender, ) { // first, sends handshake if hash == "root" { perform_handshake(sd, username, server_ip, event_tx, false); /*if let Some(data) = construct_message( messages_structure::ROOTREQUEST, Vec::new(), generate_id(), sd.cryptopair_ref(), ) { if let Some(peerinfo) = sd.handshake_ref() { sd.senders_ref() .send_via(0, data, peerinfo.ip.to_string(), false); } }*/ } else { // envoyer un datum request } } #[cfg(test)] mod tests { use std::net::{IpAddr, Ipv4Addr}; use super::*; /*#[test] fn creating_cryptographic_signature() { let mut hh = HandshakeHistory::new(); hh.add_new_handshake( 20, "putain".to_string(), SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 1), ); }*/ }