Factor out UdpSocket::accepts.
This commit is contained in:
parent
b4d6a53e34
commit
02b699e18c
|
@ -371,12 +371,12 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
|
||||||
|
|
||||||
for udp_socket in sockets.iter_mut().filter_map(
|
for udp_socket in sockets.iter_mut().filter_map(
|
||||||
<Socket as AsSocket<UdpSocket>>::try_as_socket) {
|
<Socket as AsSocket<UdpSocket>>::try_as_socket) {
|
||||||
|
if !udp_socket.accepts(&ip_repr, &udp_repr) { continue }
|
||||||
|
|
||||||
match udp_socket.process(&ip_repr, &udp_repr) {
|
match udp_socket.process(&ip_repr, &udp_repr) {
|
||||||
// The packet is valid and handled by socket.
|
// The packet is valid and handled by socket.
|
||||||
Ok(()) => return Ok(Packet::None),
|
Ok(()) => return Ok(Packet::None),
|
||||||
// The packet isn't addressed to the socket.
|
// The packet is malformed, or the socket buffer is full.
|
||||||
Err(Error::Rejected) => continue,
|
|
||||||
// The packet is malformed, or addressed to the socket but cannot be accepted.
|
|
||||||
Err(e) => return Err(e)
|
Err(e) => return Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,11 +179,16 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
|
||||||
Ok((length, endpoint))
|
Ok((length, endpoint))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn process(&mut self, ip_repr: &IpRepr, repr: &UdpRepr) -> Result<()> {
|
pub(crate) fn accepts(&self, ip_repr: &IpRepr, repr: &UdpRepr) -> bool {
|
||||||
// Reject packets with a wrong destination.
|
if self.endpoint.port != repr.dst_port { return false }
|
||||||
if self.endpoint.port != repr.dst_port { return Err(Error::Rejected) }
|
|
||||||
if !self.endpoint.addr.is_unspecified() &&
|
if !self.endpoint.addr.is_unspecified() &&
|
||||||
self.endpoint.addr != ip_repr.dst_addr() { return Err(Error::Rejected) }
|
self.endpoint.addr != ip_repr.dst_addr() { return false }
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn process(&mut self, ip_repr: &IpRepr, repr: &UdpRepr) -> Result<()> {
|
||||||
|
debug_assert!(self.accepts(ip_repr, repr));
|
||||||
|
|
||||||
let packet_buf = self.rx_buffer.enqueue_one_with(|buf| buf.resize(repr.payload.len()))?;
|
let packet_buf = self.rx_buffer.enqueue_one_with(|buf| buf.resize(repr.payload.len()))?;
|
||||||
packet_buf.as_mut().copy_from_slice(repr.payload);
|
packet_buf.as_mut().copy_from_slice(repr.payload);
|
||||||
|
@ -351,10 +356,12 @@ mod test {
|
||||||
assert!(!socket.can_recv());
|
assert!(!socket.can_recv());
|
||||||
assert_eq!(socket.recv(), Err(Error::Exhausted));
|
assert_eq!(socket.recv(), Err(Error::Exhausted));
|
||||||
|
|
||||||
|
assert!(socket.accepts(&REMOTE_IP_REPR, &REMOTE_UDP_REPR));
|
||||||
assert_eq!(socket.process(&REMOTE_IP_REPR, &REMOTE_UDP_REPR),
|
assert_eq!(socket.process(&REMOTE_IP_REPR, &REMOTE_UDP_REPR),
|
||||||
Ok(()));
|
Ok(()));
|
||||||
assert!(socket.can_recv());
|
assert!(socket.can_recv());
|
||||||
|
|
||||||
|
assert!(socket.accepts(&REMOTE_IP_REPR, &REMOTE_UDP_REPR));
|
||||||
assert_eq!(socket.process(&REMOTE_IP_REPR, &REMOTE_UDP_REPR),
|
assert_eq!(socket.process(&REMOTE_IP_REPR, &REMOTE_UDP_REPR),
|
||||||
Err(Error::Exhausted));
|
Err(Error::Exhausted));
|
||||||
assert_eq!(socket.recv(), Ok((&b"abcdef"[..], REMOTE_END)));
|
assert_eq!(socket.recv(), Ok((&b"abcdef"[..], REMOTE_END)));
|
||||||
|
@ -366,6 +373,7 @@ mod test {
|
||||||
let mut socket = socket(buffer(1), buffer(0));
|
let mut socket = socket(buffer(1), buffer(0));
|
||||||
assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
|
assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
|
||||||
|
|
||||||
|
assert!(socket.accepts(&REMOTE_IP_REPR, &REMOTE_UDP_REPR));
|
||||||
assert_eq!(socket.process(&REMOTE_IP_REPR, &REMOTE_UDP_REPR),
|
assert_eq!(socket.process(&REMOTE_IP_REPR, &REMOTE_UDP_REPR),
|
||||||
Ok(()));
|
Ok(()));
|
||||||
|
|
||||||
|
@ -380,7 +388,37 @@ mod test {
|
||||||
assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
|
assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
|
||||||
|
|
||||||
let udp_repr = UdpRepr { payload: &[0; 100][..], ..REMOTE_UDP_REPR };
|
let udp_repr = UdpRepr { payload: &[0; 100][..], ..REMOTE_UDP_REPR };
|
||||||
|
assert!(socket.accepts(&REMOTE_IP_REPR, &udp_repr));
|
||||||
assert_eq!(socket.process(&REMOTE_IP_REPR, &udp_repr),
|
assert_eq!(socket.process(&REMOTE_IP_REPR, &udp_repr),
|
||||||
Err(Error::Truncated));
|
Err(Error::Truncated));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_doesnt_accept_wrong_port() {
|
||||||
|
let mut socket = socket(buffer(1), buffer(0));
|
||||||
|
assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
|
||||||
|
|
||||||
|
let mut udp_repr = REMOTE_UDP_REPR;
|
||||||
|
assert!(socket.accepts(&REMOTE_IP_REPR, &udp_repr));
|
||||||
|
udp_repr.dst_port += 1;
|
||||||
|
assert!(!socket.accepts(&REMOTE_IP_REPR, &udp_repr));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_doesnt_accept_wrong_ip() {
|
||||||
|
let ip_repr = IpRepr::Ipv4(Ipv4Repr {
|
||||||
|
src_addr: Ipv4Address([10, 0, 0, 2]),
|
||||||
|
dst_addr: Ipv4Address([10, 0, 0, 10]),
|
||||||
|
protocol: IpProtocol::Udp,
|
||||||
|
payload_len: 8 + 6
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut port_bound_socket = socket(buffer(1), buffer(0));
|
||||||
|
assert_eq!(port_bound_socket.bind(LOCAL_PORT), Ok(()));
|
||||||
|
assert!(port_bound_socket.accepts(&ip_repr, &REMOTE_UDP_REPR));
|
||||||
|
|
||||||
|
let mut ip_bound_socket = socket(buffer(1), buffer(0));
|
||||||
|
assert_eq!(ip_bound_socket.bind(LOCAL_END), Ok(()));
|
||||||
|
assert!(!ip_bound_socket.accepts(&ip_repr, &REMOTE_UDP_REPR));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue