Simplify. NFC.
parent
0d7a6255f6
commit
7c0bae7d36
|
@ -382,52 +382,44 @@ impl<'b, 'c, DeviceT> Interface<'b, 'c, DeviceT>
|
|||
let mut neighbor_addr = None;
|
||||
let mut device_result = Ok(());
|
||||
let &mut Self { ref mut device, ref mut inner } = self;
|
||||
|
||||
macro_rules! respond {
|
||||
($response:expr) => ({
|
||||
let response = $response;
|
||||
neighbor_addr = response.neighbor_addr();
|
||||
let tx_token = device.transmit().ok_or(Error::Exhausted)?;
|
||||
device_result = inner.dispatch(tx_token, timestamp, response);
|
||||
device_result
|
||||
})
|
||||
}
|
||||
|
||||
let socket_result =
|
||||
match *socket {
|
||||
#[cfg(feature = "socket-raw")]
|
||||
Socket::Raw(ref mut socket) =>
|
||||
socket.dispatch(|response| {
|
||||
let response = Packet::Raw(response);
|
||||
neighbor_addr = response.neighbor_addr();
|
||||
let tx_token = device.transmit().ok_or(Error::Exhausted)?;
|
||||
device_result = inner.dispatch(tx_token, timestamp, response);
|
||||
device_result
|
||||
}, &caps.checksum),
|
||||
socket.dispatch(&caps.checksum, |response|
|
||||
respond!(Packet::Raw(response))),
|
||||
#[cfg(all(feature = "socket-icmp", feature = "proto-ipv4"))]
|
||||
Socket::Icmp(ref mut socket) =>
|
||||
socket.dispatch(&caps, |response| {
|
||||
let tx_token = device.transmit().ok_or(Error::Exhausted)?;
|
||||
device_result = match response {
|
||||
match response {
|
||||
#[cfg(feature = "proto-ipv4")]
|
||||
(IpRepr::Ipv4(ipv4_repr), icmpv4_repr) => {
|
||||
let response = Packet::Icmpv4((ipv4_repr, icmpv4_repr));
|
||||
neighbor_addr = response.neighbor_addr();
|
||||
inner.dispatch(tx_token, timestamp, response)
|
||||
}
|
||||
_ => Err(Error::Unaddressable),
|
||||
};
|
||||
device_result
|
||||
(IpRepr::Ipv4(ipv4_repr), icmpv4_repr) =>
|
||||
respond!(Packet::Icmpv4((ipv4_repr, icmpv4_repr))),
|
||||
_ => Err(Error::Unaddressable)
|
||||
}
|
||||
}),
|
||||
#[cfg(feature = "socket-udp")]
|
||||
Socket::Udp(ref mut socket) =>
|
||||
socket.dispatch(|response| {
|
||||
let response = Packet::Udp(response);
|
||||
neighbor_addr = response.neighbor_addr();
|
||||
let tx_token = device.transmit().ok_or(Error::Exhausted)?;
|
||||
device_result = inner.dispatch(tx_token, timestamp, response);
|
||||
device_result
|
||||
}),
|
||||
socket.dispatch(|response|
|
||||
respond!(Packet::Udp(response))),
|
||||
#[cfg(feature = "socket-tcp")]
|
||||
Socket::Tcp(ref mut socket) =>
|
||||
socket.dispatch(timestamp, &caps, |response| {
|
||||
let response = Packet::Tcp(response);
|
||||
neighbor_addr = response.neighbor_addr();
|
||||
let tx_token = device.transmit().ok_or(Error::Exhausted)?;
|
||||
device_result = inner.dispatch(tx_token, timestamp, response);
|
||||
device_result
|
||||
}),
|
||||
socket.dispatch(timestamp, &caps, |response|
|
||||
respond!(Packet::Tcp(response))),
|
||||
Socket::__Nonexhaustive(_) => unreachable!()
|
||||
};
|
||||
|
||||
match (device_result, socket_result) {
|
||||
(Err(Error::Exhausted), _) => break, // nowhere to transmit
|
||||
(Ok(()), Err(Error::Exhausted)) => (), // nothing to transmit
|
||||
|
|
|
@ -183,7 +183,7 @@ impl<'a, 'b> RawSocket<'a, 'b> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn dispatch<F>(&mut self, emit: F, checksum_caps: &ChecksumCapabilities) ->
|
||||
pub(crate) fn dispatch<F>(&mut self, checksum_caps: &ChecksumCapabilities, emit: F) ->
|
||||
Result<()>
|
||||
where F: FnOnce((IpRepr, &[u8])) -> Result<()> {
|
||||
fn prepare<'a>(protocol: IpProtocol, buffer: &'a mut [u8],
|
||||
|
@ -301,48 +301,50 @@ mod test {
|
|||
#[test]
|
||||
#[cfg(feature = "proto-ipv4")]
|
||||
fn test_send_dispatch() {
|
||||
let checksum_caps = &ChecksumCapabilities::default();
|
||||
let mut socket = ipv4_locals::socket(buffer(0), buffer(1));
|
||||
|
||||
assert!(socket.can_send());
|
||||
assert_eq!(socket.dispatch(|_| unreachable!(), &ChecksumCapabilities::default()),
|
||||
assert_eq!(socket.dispatch(&checksum_caps, |_| unreachable!()),
|
||||
Err(Error::Exhausted));
|
||||
|
||||
assert_eq!(socket.send_slice(&ipv4_locals::PACKET_BYTES[..]), Ok(()));
|
||||
assert_eq!(socket.send_slice(b""), Err(Error::Exhausted));
|
||||
assert!(!socket.can_send());
|
||||
|
||||
assert_eq!(socket.dispatch(|(ip_repr, ip_payload)| {
|
||||
assert_eq!(socket.dispatch(&checksum_caps, |(ip_repr, ip_payload)| {
|
||||
assert_eq!(ip_repr, ipv4_locals::HEADER_REPR);
|
||||
assert_eq!(ip_payload, &ipv4_locals::PACKET_PAYLOAD);
|
||||
Err(Error::Unaddressable)
|
||||
}, &ChecksumCapabilities::default()), Err(Error::Unaddressable));
|
||||
}), Err(Error::Unaddressable));
|
||||
assert!(!socket.can_send());
|
||||
|
||||
assert_eq!(socket.dispatch(|(ip_repr, ip_payload)| {
|
||||
assert_eq!(socket.dispatch(&checksum_caps, |(ip_repr, ip_payload)| {
|
||||
assert_eq!(ip_repr, ipv4_locals::HEADER_REPR);
|
||||
assert_eq!(ip_payload, &ipv4_locals::PACKET_PAYLOAD);
|
||||
Ok(())
|
||||
}, &ChecksumCapabilities::default()), Ok(()));
|
||||
}), Ok(()));
|
||||
assert!(socket.can_send());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "proto-ipv4")]
|
||||
fn test_send_illegal() {
|
||||
let checksum_caps = &ChecksumCapabilities::default();
|
||||
let mut socket = ipv4_locals::socket(buffer(0), buffer(1));
|
||||
|
||||
let mut wrong_version = ipv4_locals::PACKET_BYTES.clone();
|
||||
Ipv4Packet::new(&mut wrong_version).set_version(5);
|
||||
|
||||
assert_eq!(socket.send_slice(&wrong_version[..]), Ok(()));
|
||||
assert_eq!(socket.dispatch(|_| unreachable!(), &ChecksumCapabilities::default()),
|
||||
assert_eq!(socket.dispatch(&checksum_caps, |_| unreachable!()),
|
||||
Ok(()));
|
||||
|
||||
let mut wrong_protocol = ipv4_locals::PACKET_BYTES.clone();
|
||||
Ipv4Packet::new(&mut wrong_protocol).set_protocol(IpProtocol::Tcp);
|
||||
|
||||
assert_eq!(socket.send_slice(&wrong_protocol[..]), Ok(()));
|
||||
assert_eq!(socket.dispatch(|_| unreachable!(), &ChecksumCapabilities::default()),
|
||||
assert_eq!(socket.dispatch(&checksum_caps, |_| unreachable!()),
|
||||
Ok(()));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue