use std::{ fs::File, io::{Read, Cursor}, str::FromStr, net::SocketAddr, }; use tokio::{ io::{AsyncWriteExt, AsyncReadExt}, net::TcpStream, }; use ciph::salsa::{Psk, Connector, Randomness}; #[tokio::main] async fn main() -> Result<(), Box> { const PSK_B64: &str = include_str!("example.psk"); let psk = Psk::from_str(PSK_B64)?; let connector = Connector::new(psk, Randomness::Entropy); let args: Vec = std::env::args() .collect(); assert!(args.len() >= 3); let connect_addr = args[1].to_owned(); let addr = SocketAddr::from_str(connect_addr.as_str())?; let tcp_stream = TcpStream::connect(addr).await?; let connect = connector.connect(tcp_stream); let mut stream = connect.await?; // Slurp our file. let filename = args[2].to_owned(); let mut file =File::open(filename.as_str())?; let mut file_b = Vec::new(); file.read_to_end(&mut file_b)?; let length = file_b.len(); println!("File {} is {} bytes.", &filename, length); let mut cursor = Cursor::new(file_b); let mut received = Vec::new(); let mut buffer: [u8; 1024 * 64] = [0; 1024 * 64]; loop { stream.write_buf(&mut cursor).await?; stream.flush().await?; let read = stream.read(&mut buffer).await?; let (live, _) = buffer.split_at(read); received.extend_from_slice(live); print!("."); if received.len() >= length { break; } } println!("\nEchoed..."); assert_eq!(received.as_slice(), cursor.get_ref().as_slice()); println!("Echo equivalent!"); Ok(()) }