Fix data retransmission on repeating ACKs
This commit is contained in:
parent
97c452a623
commit
9f0dfe6073
4 changed files with 15 additions and 14 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -4,4 +4,4 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tftpd"
|
name = "tftpd"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tftpd"
|
name = "tftpd"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
authors = ["Altuğ Bakan <mail@alt.ug>"]
|
authors = ["Altuğ Bakan <mail@alt.ug>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Multithreaded TFTP server daemon"
|
description = "Multithreaded TFTP server daemon"
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ impl Server {
|
||||||
"file access violation",
|
"file access violation",
|
||||||
),
|
),
|
||||||
ErrorCode::FileExists => Ok(Worker::send(
|
ErrorCode::FileExists => Ok(Worker::send(
|
||||||
self.socket.local_addr().unwrap(),
|
self.socket.local_addr()?,
|
||||||
*to,
|
*to,
|
||||||
file_path.to_path_buf(),
|
file_path.to_path_buf(),
|
||||||
options.to_vec(),
|
options.to_vec(),
|
||||||
|
|
@ -127,7 +127,7 @@ impl Server {
|
||||||
"file access violation",
|
"file access violation",
|
||||||
),
|
),
|
||||||
ErrorCode::FileNotFound => Ok(Worker::receive(
|
ErrorCode::FileNotFound => Ok(Worker::receive(
|
||||||
self.socket.local_addr().unwrap(),
|
self.socket.local_addr()?,
|
||||||
*to,
|
*to,
|
||||||
file_path.to_path_buf(),
|
file_path.to_path_buf(),
|
||||||
options.to_vec(),
|
options.to_vec(),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use std::{
|
||||||
net::{SocketAddr, UdpSocket},
|
net::{SocketAddr, UdpSocket},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
thread,
|
thread,
|
||||||
time::Duration,
|
time::{Duration, SystemTime},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{ErrorCode, Message, OptionType, Packet, TransferOption};
|
use crate::{ErrorCode, Message, OptionType, Packet, TransferOption};
|
||||||
|
|
@ -111,7 +111,7 @@ fn send_file(
|
||||||
file_path: &PathBuf,
|
file_path: &PathBuf,
|
||||||
options: &mut Vec<TransferOption>,
|
options: &mut Vec<TransferOption>,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let mut file = File::open(file_path).unwrap();
|
let mut file = File::open(file_path)?;
|
||||||
let worker_options = parse_options(options, &WorkType::Send(file.metadata()?.len()))?;
|
let worker_options = parse_options(options, &WorkType::Send(file.metadata()?.len()))?;
|
||||||
|
|
||||||
let mut block_number = 1;
|
let mut block_number = 1;
|
||||||
|
|
@ -120,8 +120,12 @@ fn send_file(
|
||||||
let size = file.read(&mut chunk)?;
|
let size = file.read(&mut chunk)?;
|
||||||
|
|
||||||
let mut retry_cnt = 0;
|
let mut retry_cnt = 0;
|
||||||
|
let mut time = SystemTime::now() - Duration::from_secs(DEFAULT_TIMEOUT_SECS);
|
||||||
loop {
|
loop {
|
||||||
|
if time.elapsed()? >= Duration::from_secs(DEFAULT_TIMEOUT_SECS) {
|
||||||
Message::send_data(socket, block_number, chunk[..size].to_vec())?;
|
Message::send_data(socket, block_number, chunk[..size].to_vec())?;
|
||||||
|
time = SystemTime::now();
|
||||||
|
}
|
||||||
|
|
||||||
match Message::recv(socket) {
|
match Message::recv(socket) {
|
||||||
Ok(Packet::Ack(received_block_number)) => {
|
Ok(Packet::Ack(received_block_number)) => {
|
||||||
|
|
@ -131,7 +135,7 @@ fn send_file(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Packet::Error { code, msg }) => {
|
Ok(Packet::Error { code, msg }) => {
|
||||||
return Err(format!("Received error code {code}, with message {msg}").into());
|
return Err(format!("Received error code {code}: {msg}").into());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
retry_cnt += 1;
|
retry_cnt += 1;
|
||||||
|
|
@ -184,15 +188,12 @@ fn receive_file(
|
||||||
Ok(Packet::Error { code, msg }) => {
|
Ok(Packet::Error { code, msg }) => {
|
||||||
return Err(format!("Received error code {code}: {msg}").into());
|
return Err(format!("Received error code {code}: {msg}").into());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
_ => {
|
||||||
retry_cnt += 1;
|
retry_cnt += 1;
|
||||||
if retry_cnt == MAX_RETRIES {
|
if retry_cnt == MAX_RETRIES {
|
||||||
return Err(
|
return Err(format!("Transfer timed out after {MAX_RETRIES} tries").into());
|
||||||
format!("Transfer timed out after {MAX_RETRIES} tries: {err}").into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,7 +206,7 @@ fn receive_file(
|
||||||
println!(
|
println!(
|
||||||
"Received {} from {}",
|
"Received {} from {}",
|
||||||
file_path.file_name().unwrap().to_str().unwrap(),
|
file_path.file_name().unwrap().to_str().unwrap(),
|
||||||
socket.peer_addr().unwrap()
|
socket.peer_addr()?
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue