// 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 pub use crate::message_handling::*; use std::{ collections::{HashMap, VecDeque}, net::{AddrParseError, Ipv4Addr, SocketAddr}, ops::Add, process::Command, sync::{Arc, Mutex}, thread::{self, JoinHandle}, time::{self, Duration, SystemTime}, }; use crate::{ NetworkEvent, cryptographic_signature::CryptographicSignature, messages_channels::MultipleSenders, threads_handling::Worker, }; 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, } #[derive(Debug, Clone)] pub struct HandshakeHistory { pub username_k_peerinfo_v: Arc>>, ip_k_peerinfo_v: Arc>>, } impl HandshakeHistory { pub fn new() -> HandshakeHistory { HandshakeHistory { username_k_peerinfo_v: Arc::new(Mutex::new(HashMap::new())), ip_k_peerinfo_v: Arc::new(Mutex::new(HashMap::new())), } } pub fn get_peer_info_username(&self, username: String) -> Option { //self.username_k_peerinfo_v.get(&username).clone() let guard = self.username_k_peerinfo_v.lock().unwrap(); guard.get(&username).cloned() } pub fn get_peer_info_ip(&self, ip: String) -> Option { let guard = self.ip_k_peerinfo_v.lock().unwrap(); guard.get(&ip).cloned() } pub fn update_peer_info(&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, }; let mut guardb = self.ip_k_peerinfo_v.lock().unwrap(); guardb.insert(ip.to_string(), new_peer_info.clone()); let mut guard = self.username_k_peerinfo_v.lock().unwrap(); guard.insert(username.to_string(), new_peer_info); println!( "handshake added: {}, {}, {}", username.to_string(), ip.to_string(), guard.len(), ); } Err(e) => eprintln!("parse error: {}", e), }, None => { eprintln!("no peer info found in hashmap") } } } pub fn get_username_peerinfo_map(&self) -> Arc>> { self.username_k_peerinfo_v.clone() } pub fn add_new_handshake(&self, hash: VerifyingKey, username: String, ip: SocketAddr) { let peerinfo = PeerInfo { username: username.clone(), pubkey: hash, ip, }; let mut guard = self.username_k_peerinfo_v.lock().unwrap(); guard.insert(username, peerinfo.clone()); let mut guardb = self.ip_k_peerinfo_v.lock().unwrap(); guardb.insert(ip.to_string(), peerinfo.clone()); } } pub fn update_handshake( senders: Arc, crypto_pair: Arc, messages_list: Arc>>, username_k_peerinfo_v: Arc>>, ) -> Worker { let map_for_thread = username_k_peerinfo_v.clone(); let handle = thread::spawn(move || { loop { let guard = map_for_thread.lock().unwrap(); for (peer, peerinfo) in guard.iter() { let id = generate_id(); let mut map = messages_list.lock().unwrap(); map.insert(id, EventType::Ping); let pingrequest = construct_message(PING, Vec::new(), id, &crypto_pair); if let Some(ping) = pingrequest { senders.add_message_to_retry_queue( ping.clone(), peerinfo.ip.to_string(), false, ); senders.send_dispatch( ping, peerinfo.ip.to_string(), false, messages_list.clone(), ); } } drop(guard); thread::sleep(Duration::from_secs(60)); } }); Worker::spawn(handle, crate::threads_handling::WorkerType::PING) } #[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), ); }*/ }