Name update
This commit is contained in:
+49
-15
@@ -45,7 +45,12 @@ impl TftpServer {
|
||||
clients: Arc<ClientRegistry>,
|
||||
metrics: openpxe_core::Metrics,
|
||||
) -> Self {
|
||||
Self { bind, port, clients, metrics }
|
||||
Self {
|
||||
bind,
|
||||
port,
|
||||
clients,
|
||||
metrics,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(self) -> anyhow::Result<()> {
|
||||
@@ -86,7 +91,9 @@ async fn handle_rrq(
|
||||
let Some(req) = parse_rrq(&packet) else {
|
||||
return Ok(());
|
||||
};
|
||||
let Request { filename, options, .. } = req;
|
||||
let Request {
|
||||
filename, options, ..
|
||||
} = req;
|
||||
|
||||
// Per-transfer ephemeral socket.
|
||||
let sock = bind_udp(bind_ip, 0)?;
|
||||
@@ -98,7 +105,9 @@ async fn handle_rrq(
|
||||
&peer.ip().to_string(),
|
||||
Some(peer.ip()),
|
||||
None,
|
||||
ClientEvent::TftpRead { file: filename.clone() },
|
||||
ClientEvent::TftpRead {
|
||||
file: filename.clone(),
|
||||
},
|
||||
);
|
||||
return Ok(());
|
||||
};
|
||||
@@ -112,7 +121,9 @@ async fn handle_rrq(
|
||||
&peer.ip().to_string(),
|
||||
Some(peer.ip()),
|
||||
None,
|
||||
ClientEvent::TftpRead { file: filename.clone() },
|
||||
ClientEvent::TftpRead {
|
||||
file: filename.clone(),
|
||||
},
|
||||
);
|
||||
|
||||
// Negotiate options.
|
||||
@@ -173,7 +184,9 @@ async fn handle_rrq(
|
||||
|
||||
// Send one window worth of DATA.
|
||||
for _ in 0..window {
|
||||
if offset >= total { break; }
|
||||
if offset >= total {
|
||||
break;
|
||||
}
|
||||
let end = (offset + blksize).min(total);
|
||||
let chunk = &file_bytes[offset..end];
|
||||
let pkt = encode_data(block_no, chunk);
|
||||
@@ -255,20 +268,30 @@ struct Request {
|
||||
}
|
||||
|
||||
fn parse_rrq(pkt: &[u8]) -> Option<Request> {
|
||||
if pkt.len() < 4 { return None; }
|
||||
if pkt.len() < 4 {
|
||||
return None;
|
||||
}
|
||||
let op = u16::from_be_bytes([pkt[0], pkt[1]]);
|
||||
if op != OP_RRQ { return None; }
|
||||
if op != OP_RRQ {
|
||||
return None;
|
||||
}
|
||||
let mut rest = &pkt[2..];
|
||||
let filename = read_cstr(&mut rest)?;
|
||||
let mode = read_cstr(&mut rest)?;
|
||||
let mut options = Vec::new();
|
||||
while !rest.is_empty() {
|
||||
let Some(k) = read_cstr(&mut rest) else { break };
|
||||
if k.is_empty() { break; }
|
||||
if k.is_empty() {
|
||||
break;
|
||||
}
|
||||
let v = read_cstr(&mut rest).unwrap_or_default();
|
||||
options.push((k.to_ascii_lowercase(), v));
|
||||
}
|
||||
Some(Request { filename, mode, options })
|
||||
Some(Request {
|
||||
filename,
|
||||
mode,
|
||||
options,
|
||||
})
|
||||
}
|
||||
|
||||
fn read_cstr(buf: &mut &[u8]) -> Option<String> {
|
||||
@@ -316,8 +339,12 @@ async fn recv_ack(sock: &UdpSocket, peer: SocketAddr) -> anyhow::Result<u16> {
|
||||
let mut buf = [0u8; 32];
|
||||
loop {
|
||||
let (n, from) = sock.recv_from(&mut buf).await?;
|
||||
if from.ip() != peer.ip() { continue; }
|
||||
if n < 4 { continue; }
|
||||
if from.ip() != peer.ip() {
|
||||
continue;
|
||||
}
|
||||
if n < 4 {
|
||||
continue;
|
||||
}
|
||||
let op = u16::from_be_bytes([buf[0], buf[1]]);
|
||||
match op {
|
||||
OP_ACK => return Ok(u16::from_be_bytes([buf[2], buf[3]])),
|
||||
@@ -344,14 +371,19 @@ async fn wait_for_ack(
|
||||
Ok(Ok(_)) => {}
|
||||
Ok(Err(_)) | Err(_) => {
|
||||
tries += 1;
|
||||
if tries > 5 { return Ok(false); }
|
||||
if tries > 5 {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn bind_udp(bind: IpAddr, port: u16) -> anyhow::Result<UdpSocket> {
|
||||
let domain = match bind { IpAddr::V4(_) => Domain::IPV4, IpAddr::V6(_) => Domain::IPV6 };
|
||||
let domain = match bind {
|
||||
IpAddr::V4(_) => Domain::IPV4,
|
||||
IpAddr::V6(_) => Domain::IPV6,
|
||||
};
|
||||
let sock = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))?;
|
||||
sock.set_reuse_address(true)?;
|
||||
sock.set_nonblocking(true)?;
|
||||
@@ -382,7 +414,9 @@ pub fn plan_window(
|
||||
let mut o = offset;
|
||||
let mut b = starting_block;
|
||||
for _ in 0..window {
|
||||
if o >= total { break; }
|
||||
if o >= total {
|
||||
break;
|
||||
}
|
||||
let end = (o + blksize).min(total);
|
||||
out.push((b, end - o));
|
||||
o = end;
|
||||
@@ -453,7 +487,7 @@ mod tests {
|
||||
assert_eq!(p, vec![(65534, 1024), (65535, 1024)]);
|
||||
let p2 = plan_window(2048, 2048, 1024, 2, 0);
|
||||
assert!(p2.is_empty()); // nothing past EOF
|
||||
// And a cross-boundary case:
|
||||
// And a cross-boundary case:
|
||||
let p3 = plan_window(3072, 0, 1024, 3, 65535);
|
||||
assert_eq!(p3, vec![(65535, 1024), (0, 1024), (1, 1024)]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user