Browse Source

Fix ACK validation of TCP RST packets.

whitequark 8 years ago
parent
commit
3286e8a701
2 changed files with 23 additions and 5 deletions
  1. 9 5
      examples/smoltcpserver.rs
  2. 14 0
      src/socket/tcp.rs

+ 9 - 5
examples/smoltcpserver.rs

@@ -67,11 +67,6 @@ fn main() {
 
     let mut tcp_6969_connected = false;
     loop {
-        match iface.poll() {
-            Ok(()) => (),
-            Err(e) => debug!("poll error: {}", e)
-        }
-
         {
             let socket: &mut UdpSocket = iface.sockets()[0].as_socket();
             let client = match socket.recv() {
@@ -98,6 +93,10 @@ fn main() {
 
         {
             let socket: &mut TcpSocket = iface.sockets()[1].as_socket();
+            if !socket.is_open() {
+                socket.listen(endpoint).unwrap()
+            }
+
             if socket.is_connected() && !tcp_6969_connected {
                 debug!("tcp connected");
             } else if !socket.is_connected() && tcp_6969_connected {
@@ -124,5 +123,10 @@ fn main() {
                 }
             }
         }
+
+        match iface.poll() {
+            Ok(()) => (),
+            Err(e) => debug!("poll error: {}", e)
+        }
     }
 }

+ 14 - 0
src/socket/tcp.rs

@@ -458,6 +458,8 @@ impl<'a> TcpSocket<'a> {
                     return Err(Error::Malformed)
                 }
             }
+            // Any other RST need only have a valid sequence number.
+            (_, TcpRepr { control: TcpControl::Rst, .. }) => (),
             // Every packet after the initial SYN must be an acknowledgement.
             (_, TcpRepr { ack_number: None, .. }) => {
                 net_trace!("tcp:{}:{}: expecting an ACK",
@@ -1134,6 +1136,18 @@ mod test {
         assert_eq!(s.state, State::Closed);
     }
 
+    #[test]
+    fn test_established_rst_no_ack() {
+        let mut s = socket_established();
+        send!(s, [TcpRepr {
+            control: TcpControl::Rst,
+            seq_number: REMOTE_SEQ + 1,
+            ack_number: None,
+            ..SEND_TEMPL
+        }]);
+        assert_eq!(s.state, State::Closed);
+    }
+
     // =========================================================================================//
     // Tests for the CLOSE_WAIT state.
     // =========================================================================================//