|
@@ -88,6 +88,9 @@ int sysctl_tcp_app_win __read_mostly = 31;
|
|
int sysctl_tcp_adv_win_scale __read_mostly = 1;
|
|
int sysctl_tcp_adv_win_scale __read_mostly = 1;
|
|
EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
|
|
EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
|
|
|
|
|
|
|
|
+/* rfc5961 challenge ack rate limiting */
|
|
|
|
+int sysctl_tcp_challenge_ack_limit = 100;
|
|
|
|
+
|
|
int sysctl_tcp_stdurg __read_mostly;
|
|
int sysctl_tcp_stdurg __read_mostly;
|
|
int sysctl_tcp_rfc1337 __read_mostly;
|
|
int sysctl_tcp_rfc1337 __read_mostly;
|
|
int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
|
|
int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
|
|
@@ -5247,6 +5250,23 @@ out:
|
|
}
|
|
}
|
|
#endif /* CONFIG_NET_DMA */
|
|
#endif /* CONFIG_NET_DMA */
|
|
|
|
|
|
|
|
+static void tcp_send_challenge_ack(struct sock *sk)
|
|
|
|
+{
|
|
|
|
+ /* unprotected vars, we dont care of overwrites */
|
|
|
|
+ static u32 challenge_timestamp;
|
|
|
|
+ static unsigned int challenge_count;
|
|
|
|
+ u32 now = jiffies / HZ;
|
|
|
|
+
|
|
|
|
+ if (now != challenge_timestamp) {
|
|
|
|
+ challenge_timestamp = now;
|
|
|
|
+ challenge_count = 0;
|
|
|
|
+ }
|
|
|
|
+ if (++challenge_count <= sysctl_tcp_challenge_ack_limit) {
|
|
|
|
+ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK);
|
|
|
|
+ tcp_send_ack(sk);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/* Does PAWS and seqno based validation of an incoming segment, flags will
|
|
/* Does PAWS and seqno based validation of an incoming segment, flags will
|
|
* play significant role here.
|
|
* play significant role here.
|
|
*/
|
|
*/
|
|
@@ -5283,7 +5303,16 @@ static int tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
|
|
|
|
|
|
/* Step 2: check RST bit */
|
|
/* Step 2: check RST bit */
|
|
if (th->rst) {
|
|
if (th->rst) {
|
|
- tcp_reset(sk);
|
|
|
|
|
|
+ /* RFC 5961 3.2 :
|
|
|
|
+ * If sequence number exactly matches RCV.NXT, then
|
|
|
|
+ * RESET the connection
|
|
|
|
+ * else
|
|
|
|
+ * Send a challenge ACK
|
|
|
|
+ */
|
|
|
|
+ if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt)
|
|
|
|
+ tcp_reset(sk);
|
|
|
|
+ else
|
|
|
|
+ tcp_send_challenge_ack(sk);
|
|
goto discard;
|
|
goto discard;
|
|
}
|
|
}
|
|
|
|
|