Эх сурвалжийг харах

Merge pull request #482 from quartiq/rs/issue-475/udp-rebinding

Adding UDP socket close functionality
Dario Nieuwenhuis 3 жил өмнө
parent
commit
de0586e8a8

+ 1 - 0
CHANGELOG.md

@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ## [Unreleased]
 
 - Update `managed` from 0.7 to 0.8 ([442](https://github.com/smoltcp-rs/smoltcp/pull/442))
+- udp: Add `close()` method to unbind socket.
 
 ## [0.7.3] - 2021-05-29
 

+ 27 - 0
src/socket/udp.rs

@@ -146,6 +146,22 @@ impl<'a> UdpSocket<'a> {
         Ok(())
     }
 
+    /// Close the socket.
+    pub fn close(&mut self) {
+        // Clear the bound endpoint of the socket.
+        self.endpoint = IpEndpoint::default();
+
+        // Reset the RX and TX buffers of the socket.
+        self.tx_buffer.reset();
+        self.rx_buffer.reset();
+
+        #[cfg(feature = "async")]
+        {
+            self.rx_waker.wake();
+            self.tx_waker.wake();
+        }
+    }
+
     /// Check whether the socket is open.
     #[inline]
     pub fn is_open(&self) -> bool {
@@ -624,4 +640,15 @@ mod test {
         assert_eq!(socket.process(&remote_ip_repr(), &repr, &[]), Ok(()));
         assert_eq!(socket.recv(), Ok((&[][..], REMOTE_END)));
     }
+
+    #[test]
+    fn test_closing() {
+        let recv_buffer = UdpSocketBuffer::new(vec![UdpPacketMetadata::EMPTY; 1], vec![]);
+        let mut socket = socket(recv_buffer, buffer(0));
+        assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
+
+        assert!(socket.is_open());
+        socket.close();
+        assert!(!socket.is_open());
+    }
 }

+ 21 - 0
src/storage/packet_buffer.rs

@@ -179,6 +179,13 @@ impl<'a, H> PacketBuffer<'a, H> {
     pub fn payload_capacity(&self) -> usize {
         self.payload_ring.capacity()
     }
+
+    /// Reset the packet buffer and clear any staged.
+    #[allow(unused)]
+    pub(crate) fn reset(&mut self) {
+        self.payload_ring.clear();
+        self.metadata_ring.clear();
+    }
 }
 
 #[cfg(test)]
@@ -304,4 +311,18 @@ mod test {
         assert!(buffer.dequeue().is_ok());
         assert!(buffer.enqueue(5, ()).is_ok());
     }
+
+    #[test]
+    fn clear() {
+        let mut buffer = buffer();
+
+        // Ensure enqueuing data in teh buffer fills it somewhat.
+        assert!(buffer.is_empty());
+        assert!(buffer.enqueue(6, ()).is_ok());
+
+        // Ensure that resetting the buffer causes it to be empty.
+        assert!(!buffer.is_empty());
+        buffer.reset();
+        assert!(buffer.is_empty());
+    }
 }