Commit b178f368 authored by David S. Miller's avatar David S. Miller

[TCP]: Delay tstamp state commit in input fast path until we verify csum.

parent ffedcefb
...@@ -3289,17 +3289,24 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, ...@@ -3289,17 +3289,24 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
if ((s32)(tp->rcv_tsval - tp->ts_recent) < 0) if ((s32)(tp->rcv_tsval - tp->ts_recent) < 0)
goto slow_path; goto slow_path;
/* Predicted packet is in window by definition. /* DO NOT update ts_recent here, if checksum fails
* seq == rcv_nxt and rcv_wup <= rcv_nxt. * and timestamp was corrupted part, it will result
* Hence, check seq<=rcv_wup reduces to: * in a hung connection since we will drop all
* future packets due to the PAWS test.
*/ */
if (tp->rcv_nxt == tp->rcv_wup)
tcp_store_ts_recent(tp);
} }
if (len <= tcp_header_len) { if (len <= tcp_header_len) {
/* Bulk data transfer: sender */ /* Bulk data transfer: sender */
if (len == tcp_header_len) { if (len == tcp_header_len) {
/* Predicted packet is in window by definition.
* seq == rcv_nxt and rcv_wup <= rcv_nxt.
* Hence, check seq<=rcv_wup reduces to:
*/
if (tcp_header_len ==
(sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) &&
tp->rcv_nxt == tp->rcv_wup)
tcp_store_ts_recent(tp);
/* We know that such packets are checksummed /* We know that such packets are checksummed
* on entry. * on entry.
*/ */
...@@ -3325,12 +3332,30 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, ...@@ -3325,12 +3332,30 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
NET_INC_STATS_BH(TCPHPHitsToUser); NET_INC_STATS_BH(TCPHPHitsToUser);
eaten = 1; eaten = 1;
/* Predicted packet is in window by definition.
* seq == rcv_nxt and rcv_wup <= rcv_nxt.
* Hence, check seq<=rcv_wup reduces to:
*/
if (tcp_header_len ==
(sizeof(struct tcphdr) +
TCPOLEN_TSTAMP_ALIGNED) &&
tp->rcv_nxt == tp->rcv_wup)
tcp_store_ts_recent(tp);
} }
} }
if (!eaten) { if (!eaten) {
if (tcp_checksum_complete_user(sk, skb)) if (tcp_checksum_complete_user(sk, skb))
goto csum_error; goto csum_error;
/* Predicted packet is in window by definition.
* seq == rcv_nxt and rcv_wup <= rcv_nxt.
* Hence, check seq<=rcv_wup reduces to:
*/
if (tcp_header_len ==
(sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) &&
tp->rcv_nxt == tp->rcv_wup)
tcp_store_ts_recent(tp);
if ((int)skb->truesize > sk->forward_alloc) if ((int)skb->truesize > sk->forward_alloc)
goto step5; goto step5;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment