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<dyn std::error::Error>> {
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<String> = 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?;
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(())
}