Parcourir la source

Return RST to unexpected ACK in SYN-SENT state.

Before this commit, the socket got stuck in an unusable state.
Ryan Summers il y a 4 ans
Parent
commit
bdfa44270e
1 fichiers modifiés avec 20 ajouts et 0 suppressions
  1. 20 0
      src/socket/tcp.rs

+ 20 - 0
src/socket/tcp.rs

@@ -995,6 +995,15 @@ impl<'a> TcpSocket<'a> {
                            self.meta.handle, self.local_endpoint, self.remote_endpoint);
                 return Err(Error::Dropped)
             }
+            // Any ACK in the SYN-SENT state must have the SYN flag set.
+            (State::SynSent, &TcpRepr {
+                control: TcpControl::None, ack_number: Some(_), ..
+            }) => {
+                net_debug!("{}:{}:{}: expecting a SYN|ACK",
+                           self.meta.handle, self.local_endpoint, self.remote_endpoint);
+                self.abort();
+                return Err(Error::Dropped)
+            }
             // Every acknowledgement must be for transmitted but unacknowledged data.
             (_, &TcpRepr { ack_number: Some(ack_number), .. }) => {
                 let unacknowledged = self.tx_buffer.len() + control_len;
@@ -2490,6 +2499,17 @@ mod test {
         assert_eq!(s.state, State::SynSent);
     }
 
+    #[test]
+    fn test_syn_sent_bad_ack() {
+        let mut s = socket_syn_sent();
+        send!(s, TcpRepr {
+            control: TcpControl::None,
+            ack_number: Some(TcpSeqNumber(1)),
+            ..SEND_TEMPL
+        }, Err(Error::Dropped));
+        assert_eq!(s.state, State::Closed);
+    }
+
     #[test]
     fn test_syn_sent_close() {
         let mut s = socket();