Do not send RST in response to invalid SEQ or ACK.

v0.7.x
whitequark 2017-01-16 16:58:45 +00:00
parent bd01cdef78
commit 40716a348d
2 changed files with 13 additions and 16 deletions

View File

@ -105,7 +105,7 @@ pub enum Error {
/// An incoming packet could not be recognized and was dropped.
/// E.g. a packet with an unknown EtherType.
Unrecognized,
/// An incoming packet was recognized but contained invalid data.
/// An incoming packet was recognized but contained invalid control information.
/// E.g. a packet with IPv4 EtherType but containing a value other than 4
/// in the version field.
Malformed,
@ -121,6 +121,9 @@ pub enum Error {
Exhausted,
/// An incoming packet does not match the socket endpoint.
Rejected,
/// An incoming packet was recognized by a stateful socket and contained invalid control
/// information that caused the socket to drop it.
Dropped,
#[doc(hidden)]
__Nonexhaustive
@ -137,6 +140,7 @@ impl fmt::Display for Error {
&Error::Unaddressable => write!(f, "unaddressable destination"),
&Error::Exhausted => write!(f, "buffer space exhausted"),
&Error::Rejected => write!(f, "rejected by socket"),
&Error::Dropped => write!(f, "dropped by socket"),
&Error::__Nonexhaustive => unreachable!()
}
}

View File

@ -530,13 +530,6 @@ impl<'a> TcpSocket<'a> {
if !self.remote_endpoint.addr.is_unspecified() &&
self.remote_endpoint.addr != ip_repr.src_addr() { return Err(Error::Rejected) }
// Reject packets addressed to a closed socket.
if self.state == State::Closed {
net_trace!("tcp:{}:{}:{}: packet received by a closed socket",
self.local_endpoint, ip_repr.src_addr(), repr.src_port);
return Err(Error::Malformed)
}
// Reject unacceptable acknowledgements.
match (self.state, repr) {
// The initial SYN (or whatever) cannot contain an acknowledgement.
@ -588,7 +581,7 @@ impl<'a> TcpSocket<'a> {
net_trace!("tcp:{}:{}: unacceptable ACK ({} not in {}...{})",
self.local_endpoint, self.remote_endpoint,
ack_number, self.local_seq_no, self.local_seq_no + unacknowledged);
return Err(Error::Malformed)
return Err(Error::Dropped)
}
}
}
@ -605,7 +598,7 @@ impl<'a> TcpSocket<'a> {
net_trace!("tcp:{}:{}: unacceptable SEQ ({} not in {}..)",
self.local_endpoint, self.remote_endpoint,
seq_number, next_remote_seq);
return Err(Error::Malformed)
return Err(Error::Dropped)
} else if seq_number != next_remote_seq {
net_trace!("tcp:{}:{}: duplicate SEQ ({} in ..{})",
self.local_endpoint, self.remote_endpoint,
@ -614,7 +607,7 @@ impl<'a> TcpSocket<'a> {
// of that, make sure we send the acknowledgement again.
self.remote_last_ack = next_remote_seq - 1;
self.retransmit.reset();
return Ok(())
return Err(Error::Dropped)
}
}
}
@ -1090,7 +1083,7 @@ mod test {
// Tests for the CLOSED state.
// =========================================================================================//
#[test]
fn test_closed() {
fn test_closed_reject() {
let mut s = socket();
assert_eq!(s.state, State::Closed);
@ -1389,14 +1382,14 @@ mod test {
seq_number: REMOTE_SEQ + 1,
ack_number: Some(TcpSeqNumber(LOCAL_SEQ.0 - 1)),
..SEND_TEMPL
}, Err(Error::Malformed));
}, Err(Error::Dropped));
assert_eq!(s.local_seq_no, LOCAL_SEQ + 1);
// Data not yet transmitted.
send!(s, TcpRepr {
seq_number: REMOTE_SEQ + 1,
ack_number: Some(LOCAL_SEQ + 10),
..SEND_TEMPL
}, Err(Error::Malformed));
}, Err(Error::Dropped));
assert_eq!(s.local_seq_no, LOCAL_SEQ + 1);
}
@ -1408,7 +1401,7 @@ mod test {
seq_number: REMOTE_SEQ + 1 + 256,
ack_number: Some(LOCAL_SEQ + 1),
..SEND_TEMPL
}, Err(Error::Malformed));
}, Err(Error::Dropped));
assert_eq!(s.remote_seq_no, REMOTE_SEQ + 1);
}
@ -1881,7 +1874,7 @@ mod test {
ack_number: Some(LOCAL_SEQ + 1),
payload: &b"abcdef"[..],
..SEND_TEMPL
});
}, Err(Error::Dropped));
recv!(s, [TcpRepr {
seq_number: LOCAL_SEQ + 1,
ack_number: Some(REMOTE_SEQ + 1 + 6),