Skip to content
19 changes: 17 additions & 2 deletions src/iface/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ impl Interface {

enum EgressError {
Exhausted,
MismatchedSrcIp,
Dispatch,
}

Expand All @@ -669,6 +670,12 @@ impl Interface {
let mut neighbor_addr = None;
let mut respond = |inner: &mut InterfaceInner, meta: PacketMeta, response: Packet| {
neighbor_addr = Some(response.ip_repr().dst_addr());

if !inner.has_ip_addr(response.ip_repr().src_addr()) {
net_debug!("failed to transmit IP: mismatched src addr");
return Err(EgressError::MismatchedSrcIp);
}

let t = device.transmit(inner.now).ok_or_else(|| {
net_debug!("failed to transmit IP: device exhausted");
EgressError::Exhausted
Expand Down Expand Up @@ -718,13 +725,20 @@ impl Interface {
})
}
#[cfg(feature = "socket-tcp")]
Socket::Tcp(socket) => socket.dispatch(&mut self.inner, |inner, (ip, tcp)| {
Socket::Tcp(socket) => match socket.dispatch(&mut self.inner, |inner, (ip, tcp)| {
respond(
inner,
PacketMeta::default(),
Packet::new(ip, IpPayload::Tcp(tcp)),
)
}),
}) {
Err(EgressError::MismatchedSrcIp) => {
// FIXME: Should this be `close()` or `abort()`?
socket.reset();
Err(EgressError::MismatchedSrcIp)
}
r => r,
},
#[cfg(feature = "socket-dhcpv4")]
Socket::Dhcpv4(socket) => {
socket.dispatch(&mut self.inner, |inner, (ip, udp, dhcp)| {
Expand Down Expand Up @@ -757,6 +771,7 @@ impl Interface {
neighbor_addr.expect("non-IP response packet"),
);
}
Err(EgressError::MismatchedSrcIp) => {},
Ok(()) => {}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/socket/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ impl<'a> Socket<'a> {
self.state
}

fn reset(&mut self) {
pub fn reset(&mut self) {
let rx_cap_log2 =
mem::size_of::<usize>() * 8 - self.rx_buffer.capacity().leading_zeros() as usize;

Expand Down
Loading