Browse Source

Simplify. NFC.

whitequark 7 years ago
parent
commit
8928851665
2 changed files with 33 additions and 39 deletions
  1. 23 31
      src/iface/ethernet.rs
  2. 10 8
      src/socket/raw.rs

+ 23 - 31
src/iface/ethernet.rs

@@ -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

+ 10 - 8
src/socket/raw.rs

@@ -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(()));
     }