Browse Source

Reject, not accept, TCP RST packets in LISTEN state.

These packets may have been destined for a different socket.
whitequark 8 years ago
parent
commit
65a09329cc
2 changed files with 21 additions and 20 deletions
  1. 19 18
      src/iface/ethernet.rs
  2. 2 2
      src/socket/tcp.rs

+ 19 - 18
src/iface/ethernet.rs

@@ -228,24 +228,25 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
 
                         if !handled && protocol == IpProtocol::Tcp {
                             let tcp_packet = try!(TcpPacket::new(ipv4_packet.payload()));
-
-                            let tcp_reply_repr = TcpRepr {
-                                src_port:   tcp_packet.dst_port(),
-                                dst_port:   tcp_packet.src_port(),
-                                control:    TcpControl::Rst,
-                                seq_number: tcp_packet.ack_number(),
-                                ack_number: Some(tcp_packet.seq_number() +
-                                                 tcp_packet.segment_len()),
-                                window_len: 0,
-                                payload:    &[]
-                            };
-                            let ipv4_reply_repr = Ipv4Repr {
-                                src_addr:    dst_addr,
-                                dst_addr:    src_addr,
-                                protocol:    IpProtocol::Tcp,
-                                payload_len: tcp_reply_repr.buffer_len()
-                            };
-                            response = Response::Tcpv4(ipv4_reply_repr, tcp_reply_repr);
+                            if !tcp_packet.rst() {
+                                let tcp_reply_repr = TcpRepr {
+                                    src_port:   tcp_packet.dst_port(),
+                                    dst_port:   tcp_packet.src_port(),
+                                    control:    TcpControl::Rst,
+                                    seq_number: tcp_packet.ack_number(),
+                                    ack_number: Some(tcp_packet.seq_number() +
+                                                     tcp_packet.segment_len()),
+                                    window_len: 0,
+                                    payload:    &[]
+                                };
+                                let ipv4_reply_repr = Ipv4Repr {
+                                    src_addr:    dst_addr,
+                                    dst_addr:    src_addr,
+                                    protocol:    IpProtocol::Tcp,
+                                    payload_len: tcp_reply_repr.buffer_len()
+                                };
+                                response = Response::Tcpv4(ipv4_reply_repr, tcp_reply_repr);
+                            }
                         } else if !handled {
                             let reason;
                             if protocol == IpProtocol::Udp {

+ 2 - 2
src/socket/tcp.rs

@@ -657,7 +657,7 @@ impl<'a> TcpSocket<'a> {
         match (self.state, repr) {
             // RSTs are ignored in the LISTEN state.
             (State::Listen, TcpRepr { control: TcpControl::Rst, .. }) =>
-                return Ok(()),
+                return Err(Error::Rejected),
 
             // RSTs in SYN-RECEIVED flip the socket back to the LISTEN state.
             (State::SynReceived, TcpRepr { control: TcpControl::Rst, .. }) => {
@@ -1224,7 +1224,7 @@ mod test {
             seq_number: REMOTE_SEQ,
             ack_number: None,
             ..SEND_TEMPL
-        });
+        }, Err(Error::Rejected));
     }
 
     #[test]