Overall improvements

This commit is contained in:
Altuğ Bakan 2023-05-12 07:59:53 +00:00
parent 6df9155c32
commit 9096e94f00
5 changed files with 85 additions and 85 deletions

View file

@ -32,10 +32,7 @@ pub struct Config {
impl Config { impl Config {
/// Creates a new configuration by parsing the supplied arguments. It is /// Creates a new configuration by parsing the supplied arguments. It is
/// intended for use with [`env::args()`]. /// intended for use with [`env::args()`].
pub fn new<T>(mut args: T) -> Result<Config, Box<dyn Error>> pub fn new<T: Iterator<Item = String>>(mut args: T) -> Result<Config, Box<dyn Error>> {
where
T: Iterator<Item = String>,
{
let mut config = Config { let mut config = Config {
ip_address: Ipv4Addr::new(127, 0, 0, 1), ip_address: Ipv4Addr::new(127, 0, 0, 1),
port: 69, port: 69,

View file

@ -121,15 +121,22 @@ impl Server {
ErrorCode::FileExists => { ErrorCode::FileExists => {
let worker_options = let worker_options =
parse_options(options, RequestType::Read(file_path.metadata()?.len()))?; parse_options(options, RequestType::Read(file_path.metadata()?.len()))?;
let mut socket: Box<dyn Socket>;
if self.single_port { if self.single_port {
let mut socket = create_single_socket(&self.socket, to)?; let single_socket = create_single_socket(&self.socket, to)?;
self.clients.insert(*to, single_socket.sender());
self.largest_block_size =
max(self.largest_block_size, worker_options.block_size);
socket = Box::new(single_socket);
} else {
socket = Box::new(create_multi_socket(&self.socket.local_addr()?, to)?);
}
socket.set_read_timeout(worker_options.timeout)?; socket.set_read_timeout(worker_options.timeout)?;
socket.set_write_timeout(worker_options.timeout)?; socket.set_write_timeout(worker_options.timeout)?;
self.clients.insert(*to, socket.sender());
self.largest_block_size =
max(self.largest_block_size, worker_options.block_size);
accept_request( accept_request(
&socket, &socket,
options, options,
@ -144,26 +151,6 @@ impl Server {
worker_options.window_size, worker_options.window_size,
); );
worker.send() worker.send()
} else {
let socket = create_multi_socket(&self.socket.local_addr()?, to)?;
socket.set_read_timeout(Some(worker_options.timeout))?;
socket.set_write_timeout(Some(worker_options.timeout))?;
accept_request(
&socket,
options,
RequestType::Read(file_path.metadata()?.len()),
)?;
let worker = Worker::new(
socket,
file_path.clone(),
worker_options.block_size,
worker_options.timeout,
worker_options.window_size,
);
worker.send()
}
} }
_ => Err("Unexpected error code when checking file".into()), _ => Err("Unexpected error code when checking file".into()),
} }
@ -191,15 +178,22 @@ impl Server {
), ),
ErrorCode::FileNotFound => { ErrorCode::FileNotFound => {
let worker_options = parse_options(options, RequestType::Write)?; let worker_options = parse_options(options, RequestType::Write)?;
let mut socket: Box<dyn Socket>;
if self.single_port { if self.single_port {
let mut socket = create_single_socket(&self.socket, to)?; let single_socket = create_single_socket(&self.socket, to)?;
self.clients.insert(*to, single_socket.sender());
self.largest_block_size =
max(self.largest_block_size, worker_options.block_size);
socket = Box::new(single_socket);
} else {
socket = Box::new(create_multi_socket(&self.socket.local_addr()?, to)?);
}
socket.set_read_timeout(worker_options.timeout)?; socket.set_read_timeout(worker_options.timeout)?;
socket.set_write_timeout(worker_options.timeout)?; socket.set_write_timeout(worker_options.timeout)?;
self.clients.insert(*to, socket.sender());
self.largest_block_size =
max(self.largest_block_size, worker_options.block_size);
accept_request(&socket, options, RequestType::Write)?; accept_request(&socket, options, RequestType::Write)?;
let worker = Worker::new( let worker = Worker::new(
@ -210,22 +204,6 @@ impl Server {
worker_options.window_size, worker_options.window_size,
); );
worker.receive() worker.receive()
} else {
let socket = create_multi_socket(&self.socket.local_addr()?, to)?;
socket.set_read_timeout(Some(worker_options.timeout))?;
socket.set_write_timeout(Some(worker_options.timeout))?;
accept_request(&socket, options, RequestType::Write)?;
let worker = Worker::new(
socket,
file_path.clone(),
worker_options.block_size,
worker_options.timeout,
worker_options.window_size,
);
worker.receive()
}
} }
_ => Err("Unexpected error code when checking file".into()), _ => Err("Unexpected error code when checking file".into()),
} }

View file

@ -12,9 +12,8 @@ use crate::Packet;
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5); const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5);
/// Socket `trait` is used for easy message transmission of common TFTP /// Socket `trait` is used to allow building custom sockets to be used for
/// message types. This `trait` is implemented for [`UdpSocket`] and used /// TFTP communication.
/// for abstraction of single socket communication.
pub trait Socket: Send + Sync + 'static { pub trait Socket: Send + Sync + 'static {
/// Sends a [`Packet`] to the socket's connected remote [`Socket`]. /// Sends a [`Packet`] to the socket's connected remote [`Socket`].
fn send(&self, packet: &Packet) -> Result<(), Box<dyn Error>>; fn send(&self, packet: &Packet) -> Result<(), Box<dyn Error>>;
@ -165,6 +164,36 @@ impl ServerSocket {
} }
} }
impl<T: Socket + ?Sized> Socket for Box<T> {
fn send(&self, packet: &Packet) -> Result<(), Box<dyn Error>> {
(**self).send(packet)
}
fn send_to(&self, packet: &Packet, to: &SocketAddr) -> Result<(), Box<dyn Error>> {
(**self).send_to(packet, to)
}
fn recv(&self, buf: &mut [u8]) -> Result<Packet, Box<dyn Error>> {
(**self).recv(buf)
}
fn recv_from(&self, buf: &mut [u8]) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
(**self).recv_from(buf)
}
fn remote_addr(&self) -> Result<SocketAddr, Box<dyn Error>> {
(**self).remote_addr()
}
fn set_read_timeout(&mut self, dur: Duration) -> Result<(), Box<dyn Error>> {
(**self).set_read_timeout(dur)
}
fn set_write_timeout(&mut self, dur: Duration) -> Result<(), Box<dyn Error>> {
(**self).set_write_timeout(dur)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -5,9 +5,9 @@ use std::{
io::{Read, Write}, io::{Read, Write},
}; };
/// Window `struct` is used to store chunks of data from a file. /// Window `struct` is used to store chunks of data from a file. It is
/// It is used to store the data that is being sent or received for /// used to help store the data that is being sent or received for the
/// Windowsize option. /// [RFC 7440](https://www.rfc-editor.org/rfc/rfc7440) Windowsize option.
/// ///
/// # Example /// # Example
/// ```rust /// ```rust
@ -206,8 +206,10 @@ mod tests {
.unwrap() .unwrap()
} }
#[allow(unused_must_use)]
fn clean(file_name: &str) { fn clean(file_name: &str) {
let file_name = DIR_NAME.to_string() + "/" + file_name; let file_name = DIR_NAME.to_string() + "/" + file_name;
fs::remove_file(file_name).unwrap(); fs::remove_file(file_name).unwrap();
fs::remove_dir(DIR_NAME);
} }
} }

View file

@ -28,7 +28,7 @@ const TIMEOUT_BUFFER: Duration = Duration::from_secs(1);
/// socket.connect(SocketAddr::from_str("127.0.0.1:12345").unwrap()).unwrap(); /// socket.connect(SocketAddr::from_str("127.0.0.1:12345").unwrap()).unwrap();
/// ///
/// let worker = Worker::new( /// let worker = Worker::new(
/// socket, /// Box::new(socket),
/// PathBuf::from_str("Cargo.toml").unwrap(), /// PathBuf::from_str("Cargo.toml").unwrap(),
/// 512, /// 512,
/// Duration::from_secs(1), /// Duration::from_secs(1),
@ -37,24 +37,18 @@ const TIMEOUT_BUFFER: Duration = Duration::from_secs(1);
/// ///
/// worker.send().unwrap(); /// worker.send().unwrap();
/// ``` /// ```
pub struct Worker<T> pub struct Worker<T: Socket + ?Sized> {
where socket: Box<T>,
T: Socket,
{
socket: T,
file_name: PathBuf, file_name: PathBuf,
blk_size: usize, blk_size: usize,
timeout: Duration, timeout: Duration,
windowsize: u16, windowsize: u16,
} }
impl<T> Worker<T> impl<T: Socket + ?Sized> Worker<T> {
where
T: Socket,
{
/// Creates a new [`Worker`] with the supplied options. /// Creates a new [`Worker`] with the supplied options.
pub fn new( pub fn new(
socket: T, socket: Box<T>,
file_name: PathBuf, file_name: PathBuf,
blk_size: usize, blk_size: usize,
timeout: Duration, timeout: Duration,