|
@@ -5159,6 +5159,7 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
|
|
|
const struct tcphdr *th, int syn_inerr)
|
|
|
{
|
|
|
struct tcp_sock *tp = tcp_sk(sk);
|
|
|
+ bool rst_seq_match = false;
|
|
|
|
|
|
/* RFC1323: H1. Apply PAWS check first. */
|
|
|
if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp &&
|
|
@@ -5195,13 +5196,32 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
|
|
|
|
|
|
/* Step 2: check RST bit */
|
|
|
if (th->rst) {
|
|
|
- /* RFC 5961 3.2 :
|
|
|
- * If sequence number exactly matches RCV.NXT, then
|
|
|
+ /* RFC 5961 3.2 (extend to match against SACK too if available):
|
|
|
+ * If seq num matches RCV.NXT or the right-most SACK block,
|
|
|
+ * then
|
|
|
* RESET the connection
|
|
|
* else
|
|
|
* Send a challenge ACK
|
|
|
*/
|
|
|
- if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt)
|
|
|
+ if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {
|
|
|
+ rst_seq_match = true;
|
|
|
+ } else if (tcp_is_sack(tp) && tp->rx_opt.num_sacks > 0) {
|
|
|
+ struct tcp_sack_block *sp = &tp->selective_acks[0];
|
|
|
+ int max_sack = sp[0].end_seq;
|
|
|
+ int this_sack;
|
|
|
+
|
|
|
+ for (this_sack = 1; this_sack < tp->rx_opt.num_sacks;
|
|
|
+ ++this_sack) {
|
|
|
+ max_sack = after(sp[this_sack].end_seq,
|
|
|
+ max_sack) ?
|
|
|
+ sp[this_sack].end_seq : max_sack;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (TCP_SKB_CB(skb)->seq == max_sack)
|
|
|
+ rst_seq_match = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rst_seq_match)
|
|
|
tcp_reset(sk);
|
|
|
else
|
|
|
tcp_send_challenge_ack(sk, skb);
|