Remove Message
This commit is contained in:
parent
9096e94f00
commit
51539c2733
6 changed files with 91 additions and 185 deletions
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
mod convert;
|
mod convert;
|
||||||
mod message;
|
|
||||||
mod packet;
|
mod packet;
|
||||||
mod server;
|
mod server;
|
||||||
mod socket;
|
mod socket;
|
||||||
|
|
@ -26,7 +25,6 @@ mod worker;
|
||||||
|
|
||||||
pub use config::Config;
|
pub use config::Config;
|
||||||
pub use convert::Convert;
|
pub use convert::Convert;
|
||||||
pub use message::Message;
|
|
||||||
pub use packet::ErrorCode;
|
pub use packet::ErrorCode;
|
||||||
pub use packet::Opcode;
|
pub use packet::Opcode;
|
||||||
pub use packet::OptionType;
|
pub use packet::OptionType;
|
||||||
|
|
|
||||||
133
src/message.rs
133
src/message.rs
|
|
@ -1,133 +0,0 @@
|
||||||
use std::{error::Error, net::SocketAddr};
|
|
||||||
|
|
||||||
use crate::{ErrorCode, Packet, Socket, TransferOption};
|
|
||||||
|
|
||||||
/// Message `struct` is used for easy message transmission of common TFTP
|
|
||||||
/// message types.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use std::{net::{SocketAddr, UdpSocket}, str::FromStr};
|
|
||||||
/// use tftpd::{Message, ErrorCode};
|
|
||||||
///
|
|
||||||
/// // Send a FileNotFound error.
|
|
||||||
/// Message::send_error_to(
|
|
||||||
/// &UdpSocket::bind(SocketAddr::from_str("127.0.0.1:6969").unwrap()).unwrap(),
|
|
||||||
/// &SocketAddr::from_str("127.0.0.1:1234").unwrap(),
|
|
||||||
/// ErrorCode::FileNotFound,
|
|
||||||
/// "file does not exist",
|
|
||||||
/// );
|
|
||||||
/// ```
|
|
||||||
pub struct Message;
|
|
||||||
|
|
||||||
const MAX_REQUEST_PACKET_SIZE: usize = 512;
|
|
||||||
|
|
||||||
impl Message {
|
|
||||||
/// Sends a data packet to the socket's connected remote. See
|
|
||||||
/// [`UdpSocket`] for more information about connected
|
|
||||||
/// sockets.
|
|
||||||
pub fn send_data<T: Socket>(
|
|
||||||
socket: &T,
|
|
||||||
block_num: u16,
|
|
||||||
data: Vec<u8>,
|
|
||||||
) -> Result<(), Box<dyn Error>> {
|
|
||||||
socket.send(&Packet::Data { block_num, data })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sends an acknowledgement packet to the socket's connected remote. See
|
|
||||||
/// [`UdpSocket`] for more information about connected
|
|
||||||
/// sockets.
|
|
||||||
pub fn send_ack<T: Socket>(socket: &T, block_number: u16) -> Result<(), Box<dyn Error>> {
|
|
||||||
socket.send(&Packet::Ack(block_number))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sends an error packet to the socket's connected remote. See
|
|
||||||
/// [`UdpSocket`] for more information about connected
|
|
||||||
/// sockets.
|
|
||||||
pub fn send_error<T: Socket>(
|
|
||||||
socket: &T,
|
|
||||||
code: ErrorCode,
|
|
||||||
msg: &str,
|
|
||||||
) -> Result<(), Box<dyn Error>> {
|
|
||||||
if socket
|
|
||||||
.send(&Packet::Error {
|
|
||||||
code,
|
|
||||||
msg: msg.to_string(),
|
|
||||||
})
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
eprintln!("could not send an error message");
|
|
||||||
};
|
|
||||||
|
|
||||||
Err(msg.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sends an error packet to the supplied [`SocketAddr`].
|
|
||||||
pub fn send_error_to<T: Socket>(
|
|
||||||
socket: &T,
|
|
||||||
to: &SocketAddr,
|
|
||||||
code: ErrorCode,
|
|
||||||
msg: &str,
|
|
||||||
) -> Result<(), Box<dyn Error>> {
|
|
||||||
if socket
|
|
||||||
.send_to(
|
|
||||||
&Packet::Error {
|
|
||||||
code,
|
|
||||||
msg: msg.to_string(),
|
|
||||||
},
|
|
||||||
to,
|
|
||||||
)
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
eprintln!("could not send an error message");
|
|
||||||
}
|
|
||||||
Err(msg.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sends an option acknowledgement packet to the socket's connected remote.
|
|
||||||
/// See [`UdpSocket`] for more information about connected sockets.
|
|
||||||
pub fn send_oack<T: Socket>(
|
|
||||||
socket: &T,
|
|
||||||
options: Vec<TransferOption>,
|
|
||||||
) -> Result<(), Box<dyn Error>> {
|
|
||||||
socket.send(&Packet::Oack(options))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Receives a packet from the socket's connected remote, and returns the
|
|
||||||
/// parsed [`Packet`]. This function cannot handle large data packets due to
|
|
||||||
/// the limited buffer size. For handling data packets, see [`Message::recv_with_size()`].
|
|
||||||
pub fn recv<T: Socket>(socket: &T) -> Result<Packet, Box<dyn Error>> {
|
|
||||||
let mut buf = [0; MAX_REQUEST_PACKET_SIZE];
|
|
||||||
socket.recv(&mut buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Receives a packet from any incoming remote request, and returns the
|
|
||||||
/// parsed [`Packet`] and the requesting [`SocketAddr`]. This function cannot handle
|
|
||||||
/// large data packets due to the limited buffer size, so it is intended for
|
|
||||||
/// only accepting incoming requests. For handling data packets, see [`Message::recv_with_size()`].
|
|
||||||
pub fn recv_from<T: Socket>(socket: &T) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
|
|
||||||
let mut buf = [0; MAX_REQUEST_PACKET_SIZE];
|
|
||||||
socket.recv_from(&mut buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Receives a data packet from the socket's connected remote, and returns the
|
|
||||||
/// parsed [`Packet`]. The received packet can actually be of any type, however,
|
|
||||||
/// this function also allows supplying the buffer size for an incoming request.
|
|
||||||
pub fn recv_with_size<T: Socket>(socket: &T, size: usize) -> Result<Packet, Box<dyn Error>> {
|
|
||||||
let mut buf = vec![0; size + 4];
|
|
||||||
socket.recv(&mut buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Receives a data packet from any incoming remote request, and returns the
|
|
||||||
/// parsed [`Packet`] and the requesting [`SocketAddr`]. The received packet can
|
|
||||||
/// actually be of any type, however, this function also allows supplying the
|
|
||||||
/// buffer size for an incoming request.
|
|
||||||
pub fn recv_from_with_size<T: Socket>(
|
|
||||||
socket: &T,
|
|
||||||
size: usize,
|
|
||||||
) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
|
|
||||||
let mut buf = vec![0; size + 4];
|
|
||||||
socket.recv_from(&mut buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{Config, Message, OptionType, ServerSocket, Socket, Worker};
|
use crate::{Config, OptionType, ServerSocket, Socket, Worker};
|
||||||
use crate::{ErrorCode, Packet, TransferOption};
|
use crate::{ErrorCode, Packet, TransferOption};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
@ -55,9 +55,9 @@ impl Server {
|
||||||
pub fn listen(&mut self) {
|
pub fn listen(&mut self) {
|
||||||
loop {
|
loop {
|
||||||
let received = if self.single_port {
|
let received = if self.single_port {
|
||||||
Message::recv_from_with_size(&self.socket, self.largest_block_size)
|
self.socket.recv_from_with_size(self.largest_block_size)
|
||||||
} else {
|
} else {
|
||||||
Message::recv_from(&self.socket)
|
Socket::recv_from(&self.socket)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok((packet, from)) = received {
|
if let Ok((packet, from)) = received {
|
||||||
|
|
@ -84,13 +84,19 @@ impl Server {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if self.route_packet(packet, &from).is_err() {
|
if self.route_packet(packet, &from).is_err() {
|
||||||
Message::send_error_to(
|
if Socket::send_to(
|
||||||
&self.socket,
|
&self.socket,
|
||||||
|
&Packet::Error {
|
||||||
|
code: ErrorCode::IllegalOperation,
|
||||||
|
msg: "invalid request".to_string(),
|
||||||
|
},
|
||||||
&from,
|
&from,
|
||||||
ErrorCode::IllegalOperation,
|
|
||||||
"invalid request",
|
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|_| eprintln!("Received invalid request"));
|
.is_err()
|
||||||
|
{
|
||||||
|
eprintln!("Could not send error packet");
|
||||||
|
};
|
||||||
|
eprintln!("Received invalid request");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -106,17 +112,21 @@ impl Server {
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let file_path = &self.directory.join(filename);
|
let file_path = &self.directory.join(filename);
|
||||||
match check_file_exists(file_path, &self.directory) {
|
match check_file_exists(file_path, &self.directory) {
|
||||||
ErrorCode::FileNotFound => Message::send_error_to(
|
ErrorCode::FileNotFound => Socket::send_to(
|
||||||
&self.socket,
|
&self.socket,
|
||||||
|
&Packet::Error {
|
||||||
|
code: ErrorCode::FileNotFound,
|
||||||
|
msg: "file does not exist".to_string(),
|
||||||
|
},
|
||||||
to,
|
to,
|
||||||
ErrorCode::FileNotFound,
|
|
||||||
"file does not exist",
|
|
||||||
),
|
),
|
||||||
ErrorCode::AccessViolation => Message::send_error_to(
|
ErrorCode::AccessViolation => Socket::send_to(
|
||||||
&self.socket,
|
&self.socket,
|
||||||
|
&Packet::Error {
|
||||||
|
code: ErrorCode::AccessViolation,
|
||||||
|
msg: "file access violation".to_string(),
|
||||||
|
},
|
||||||
to,
|
to,
|
||||||
ErrorCode::AccessViolation,
|
|
||||||
"file access violation",
|
|
||||||
),
|
),
|
||||||
ErrorCode::FileExists => {
|
ErrorCode::FileExists => {
|
||||||
let worker_options =
|
let worker_options =
|
||||||
|
|
@ -164,17 +174,21 @@ impl Server {
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let file_path = &self.directory.join(file_name);
|
let file_path = &self.directory.join(file_name);
|
||||||
match check_file_exists(file_path, &self.directory) {
|
match check_file_exists(file_path, &self.directory) {
|
||||||
ErrorCode::FileExists => Message::send_error_to(
|
ErrorCode::FileExists => Socket::send_to(
|
||||||
&self.socket,
|
&self.socket,
|
||||||
|
&Packet::Error {
|
||||||
|
code: ErrorCode::FileExists,
|
||||||
|
msg: "requested file already exists".to_string(),
|
||||||
|
},
|
||||||
to,
|
to,
|
||||||
ErrorCode::FileExists,
|
|
||||||
"requested file already exists",
|
|
||||||
),
|
),
|
||||||
ErrorCode::AccessViolation => Message::send_error_to(
|
ErrorCode::AccessViolation => Socket::send_to(
|
||||||
&self.socket,
|
&self.socket,
|
||||||
|
&Packet::Error {
|
||||||
|
code: ErrorCode::AccessViolation,
|
||||||
|
msg: "file access violation".to_string(),
|
||||||
|
},
|
||||||
to,
|
to,
|
||||||
ErrorCode::AccessViolation,
|
|
||||||
"file access violation",
|
|
||||||
),
|
),
|
||||||
ErrorCode::FileNotFound => {
|
ErrorCode::FileNotFound => {
|
||||||
let worker_options = parse_options(options, RequestType::Write)?;
|
let worker_options = parse_options(options, RequestType::Write)?;
|
||||||
|
|
@ -302,21 +316,24 @@ fn accept_request<T: Socket>(
|
||||||
request_type: RequestType,
|
request_type: RequestType,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
if !options.is_empty() {
|
if !options.is_empty() {
|
||||||
Message::send_oack(socket, options.to_vec())?;
|
socket.send(&Packet::Oack(options.to_vec()))?;
|
||||||
if let RequestType::Read(_) = request_type {
|
if let RequestType::Read(_) = request_type {
|
||||||
check_response(socket)?;
|
check_response(socket)?;
|
||||||
}
|
}
|
||||||
} else if request_type == RequestType::Write {
|
} else if request_type == RequestType::Write {
|
||||||
Message::send_ack(socket, 0)?
|
socket.send(&Packet::Ack(0))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_response<T: Socket>(socket: &T) -> Result<(), Box<dyn Error>> {
|
fn check_response<T: Socket>(socket: &T) -> Result<(), Box<dyn Error>> {
|
||||||
if let Packet::Ack(received_block_number) = Message::recv(socket)? {
|
if let Packet::Ack(received_block_number) = socket.recv()? {
|
||||||
if received_block_number != 0 {
|
if received_block_number != 0 {
|
||||||
Message::send_error(socket, ErrorCode::IllegalOperation, "invalid oack response")?;
|
socket.send(&Packet::Error {
|
||||||
|
code: ErrorCode::IllegalOperation,
|
||||||
|
msg: "invalid oack response".to_string(),
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::Packet;
|
||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
net::{SocketAddr, UdpSocket},
|
net::{SocketAddr, UdpSocket},
|
||||||
|
|
@ -8,9 +9,8 @@ use std::{
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::Packet;
|
|
||||||
|
|
||||||
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5);
|
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5);
|
||||||
|
const MAX_REQUEST_PACKET_SIZE: usize = 512;
|
||||||
|
|
||||||
/// Socket `trait` is used to allow building custom sockets to be used for
|
/// Socket `trait` is used to allow building custom sockets to be used for
|
||||||
/// TFTP communication.
|
/// TFTP communication.
|
||||||
|
|
@ -19,11 +19,29 @@ pub trait Socket: Send + Sync + 'static {
|
||||||
fn send(&self, packet: &Packet) -> Result<(), Box<dyn Error>>;
|
fn send(&self, packet: &Packet) -> Result<(), Box<dyn Error>>;
|
||||||
/// Sends a [`Packet`] to the specified remote [`Socket`].
|
/// Sends a [`Packet`] to the specified remote [`Socket`].
|
||||||
fn send_to(&self, packet: &Packet, to: &SocketAddr) -> Result<(), Box<dyn Error>>;
|
fn send_to(&self, packet: &Packet, to: &SocketAddr) -> Result<(), Box<dyn Error>>;
|
||||||
/// Receives a [`Packet`] from the socket's connected remote [`Socket`].
|
/// Receives a [`Packet`] from the socket's connected remote [`Socket`]. This
|
||||||
fn recv(&self, buf: &mut [u8]) -> Result<Packet, Box<dyn Error>>;
|
/// function cannot handle large data packets due to the limited buffer size,
|
||||||
|
/// so it is intended for only accepting incoming requests. For handling data
|
||||||
|
/// packets, see [`Socket::recv_with_size()`].
|
||||||
|
fn recv(&self) -> Result<Packet, Box<dyn Error>> {
|
||||||
|
self.recv_with_size(MAX_REQUEST_PACKET_SIZE)
|
||||||
|
}
|
||||||
|
/// Receives a data packet from the socket's connected remote, and returns the
|
||||||
|
/// parsed [`Packet`]. The received packet can actually be of any type, however,
|
||||||
|
/// this function also allows supplying the buffer size for an incoming request.
|
||||||
|
fn recv_with_size(&self, size: usize) -> Result<Packet, Box<dyn Error>>;
|
||||||
/// Receives a [`Packet`] from any remote [`Socket`] and returns the [`SocketAddr`]
|
/// Receives a [`Packet`] from any remote [`Socket`] and returns the [`SocketAddr`]
|
||||||
/// of the remote [`Socket`].
|
/// of the remote [`Socket`]. This function cannot handle large data packets
|
||||||
fn recv_from(&self, buf: &mut [u8]) -> Result<(Packet, SocketAddr), Box<dyn Error>>;
|
/// due to the limited buffer size, so it is intended for only accepting incoming
|
||||||
|
/// requests. For handling data packets, see [`Socket::recv_from_with_size()`].
|
||||||
|
fn recv_from(&self) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
|
||||||
|
self.recv_from_with_size(MAX_REQUEST_PACKET_SIZE)
|
||||||
|
}
|
||||||
|
/// Receives a data packet from any incoming remote request, and returns the
|
||||||
|
/// parsed [`Packet`] and the requesting [`SocketAddr`]. The received packet can
|
||||||
|
/// actually be of any type, however, this function also allows supplying the
|
||||||
|
/// buffer size for an incoming request.
|
||||||
|
fn recv_from_with_size(&self, size: usize) -> Result<(Packet, SocketAddr), Box<dyn Error>>;
|
||||||
/// Returns the remote [`SocketAddr`] if it exists.
|
/// Returns the remote [`SocketAddr`] if it exists.
|
||||||
fn remote_addr(&self) -> Result<SocketAddr, Box<dyn Error>>;
|
fn remote_addr(&self) -> Result<SocketAddr, Box<dyn Error>>;
|
||||||
/// Sets the read timeout for the [`Socket`].
|
/// Sets the read timeout for the [`Socket`].
|
||||||
|
|
@ -45,15 +63,17 @@ impl Socket for UdpSocket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv(&self, buf: &mut [u8]) -> Result<Packet, Box<dyn Error>> {
|
fn recv_with_size(&self, size: usize) -> Result<Packet, Box<dyn Error>> {
|
||||||
let amt = self.recv(buf)?;
|
let mut buf = vec![0; size + 4];
|
||||||
|
let amt = self.recv(&mut buf)?;
|
||||||
let packet = Packet::deserialize(&buf[..amt])?;
|
let packet = Packet::deserialize(&buf[..amt])?;
|
||||||
|
|
||||||
Ok(packet)
|
Ok(packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv_from(&self, buf: &mut [u8]) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
|
fn recv_from_with_size(&self, size: usize) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
|
||||||
let (amt, addr) = self.recv_from(buf)?;
|
let mut buf = vec![0; size + 4];
|
||||||
|
let (amt, addr) = self.recv_from(&mut buf)?;
|
||||||
let packet = Packet::deserialize(&buf[..amt])?;
|
let packet = Packet::deserialize(&buf[..amt])?;
|
||||||
|
|
||||||
Ok((packet, addr))
|
Ok((packet, addr))
|
||||||
|
|
@ -112,7 +132,7 @@ impl Socket for ServerSocket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv(&self, _buf: &mut [u8]) -> Result<Packet, Box<dyn Error>> {
|
fn recv_with_size(&self, _size: usize) -> Result<Packet, Box<dyn Error>> {
|
||||||
if let Ok(receiver) = self.receiver.lock() {
|
if let Ok(receiver) = self.receiver.lock() {
|
||||||
if let Ok(packet) = receiver.recv_timeout(self.timeout) {
|
if let Ok(packet) = receiver.recv_timeout(self.timeout) {
|
||||||
Ok(packet)
|
Ok(packet)
|
||||||
|
|
@ -124,8 +144,8 @@ impl Socket for ServerSocket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv_from(&self, buf: &mut [u8]) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
|
fn recv_from_with_size(&self, _size: usize) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
|
||||||
Ok((self.recv(buf)?, self.remote))
|
Ok((self.recv()?, self.remote))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_addr(&self) -> Result<SocketAddr, Box<dyn Error>> {
|
fn remote_addr(&self) -> Result<SocketAddr, Box<dyn Error>> {
|
||||||
|
|
@ -173,12 +193,12 @@ impl<T: Socket + ?Sized> Socket for Box<T> {
|
||||||
(**self).send_to(packet, to)
|
(**self).send_to(packet, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv(&self, buf: &mut [u8]) -> Result<Packet, Box<dyn Error>> {
|
fn recv_with_size(&self, size: usize) -> Result<Packet, Box<dyn Error>> {
|
||||||
(**self).recv(buf)
|
(**self).recv_with_size(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv_from(&self, buf: &mut [u8]) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
|
fn recv_from_with_size(&self, size: usize) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
|
||||||
(**self).recv_from(buf)
|
(**self).recv_from_with_size(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_addr(&self) -> Result<SocketAddr, Box<dyn Error>> {
|
fn remote_addr(&self) -> Result<SocketAddr, Box<dyn Error>> {
|
||||||
|
|
@ -209,7 +229,7 @@ mod tests {
|
||||||
|
|
||||||
socket.sender.lock().unwrap().send(Packet::Ack(1)).unwrap();
|
socket.sender.lock().unwrap().send(Packet::Ack(1)).unwrap();
|
||||||
|
|
||||||
let packet = socket.recv(&mut []).unwrap();
|
let packet = socket.recv().unwrap();
|
||||||
|
|
||||||
assert_eq!(packet, Packet::Ack(1));
|
assert_eq!(packet, Packet::Ack(1));
|
||||||
|
|
||||||
|
|
@ -223,7 +243,7 @@ mod tests {
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let packet = socket.recv(&mut []).unwrap();
|
let packet = socket.recv().unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
packet,
|
packet,
|
||||||
|
|
|
||||||
|
|
@ -206,10 +206,12 @@ 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);
|
if fs::remove_dir(DIR_NAME).is_err() {
|
||||||
|
// ignore removing directory, as other tests are
|
||||||
|
// still running
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::{Packet, Socket, Window};
|
||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
|
|
@ -6,8 +7,6 @@ use std::{
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Message, Packet, Socket, Window};
|
|
||||||
|
|
||||||
const MAX_RETRIES: u32 = 6;
|
const MAX_RETRIES: u32 = 6;
|
||||||
const TIMEOUT_BUFFER: Duration = Duration::from_secs(1);
|
const TIMEOUT_BUFFER: Duration = Duration::from_secs(1);
|
||||||
|
|
||||||
|
|
@ -141,7 +140,7 @@ impl<T: Socket + ?Sized> Worker<T> {
|
||||||
time = Instant::now();
|
time = Instant::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
match Message::recv(&self.socket) {
|
match self.socket.recv() {
|
||||||
Ok(Packet::Ack(received_block_number)) => {
|
Ok(Packet::Ack(received_block_number)) => {
|
||||||
let diff = received_block_number.wrapping_sub(block_number);
|
let diff = received_block_number.wrapping_sub(block_number);
|
||||||
if diff <= self.windowsize {
|
if diff <= self.windowsize {
|
||||||
|
|
@ -181,7 +180,7 @@ impl<T: Socket + ?Sized> Worker<T> {
|
||||||
let mut retry_cnt = 0;
|
let mut retry_cnt = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match Message::recv_with_size(&self.socket, self.blk_size) {
|
match self.socket.recv_with_size(self.blk_size) {
|
||||||
Ok(Packet::Data {
|
Ok(Packet::Data {
|
||||||
block_num: received_block_number,
|
block_num: received_block_number,
|
||||||
data,
|
data,
|
||||||
|
|
@ -215,7 +214,7 @@ impl<T: Socket + ?Sized> Worker<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
window.empty()?;
|
window.empty()?;
|
||||||
Message::send_ack(&self.socket, block_number)?;
|
self.socket.send(&Packet::Ack(block_number))?;
|
||||||
if size < self.blk_size {
|
if size < self.blk_size {
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
@ -231,7 +230,10 @@ fn send_window<T: Socket>(
|
||||||
mut block_num: u16,
|
mut block_num: u16,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
for frame in window.get_elements() {
|
for frame in window.get_elements() {
|
||||||
Message::send_data(socket, block_num, frame.to_vec())?;
|
socket.send(&Packet::Data {
|
||||||
|
block_num,
|
||||||
|
data: frame.to_vec(),
|
||||||
|
})?;
|
||||||
block_num = block_num.wrapping_add(1);
|
block_num = block_num.wrapping_add(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue