!92 newip tcp add RFC 5961 5.2

Merge pull request !92 from 史云飞/master
This commit is contained in:
openharmony_ci
2023-12-27 08:35:38 +00:00
committed by Gitee
+63 -5
View File
@@ -1568,7 +1568,56 @@ static void tcp_nip_ack_calc_ssthresh(struct sock *sk, u32 ack, int icsk_rto_las
}
}
static int tcp_nip_ack(struct sock *sk, const struct sk_buff *skb)
static bool __tcp_nip_oow_rate_limited(struct net *net, int mib_idx, u32 *last_oow_ack_time)
{
if (*last_oow_ack_time) {
s32 elapsed = (s32)(tcp_jiffies32 - *last_oow_ack_time);
if (elapsed >= 0 &&
elapsed < READ_ONCE(net->ipv4.sysctl_tcp_invalid_ratelimit)) {
NET_INC_STATS(net, mib_idx);
return true; /* rate-limited: don't send yet! */
}
}
*last_oow_ack_time = tcp_jiffies32;
return false; /* not rate-limited: go ahead, send dupack now! */
}
static void tcp_nip_send_challenge_ack(struct sock *sk, const struct sk_buff *skb)
{
/* unprotected vars, we dont care of overwrites */
static u32 nip_challenge_timestamp;
static unsigned int nip_challenge_count;
struct tcp_sock *tp = tcp_sk(sk);
struct net *net = sock_net(sk);
u32 count, now;
/* First check our per-socket dupack rate limit. */
if (__tcp_nip_oow_rate_limited(net,
LINUX_MIB_TCPACKSKIPPEDCHALLENGE,
&tp->last_oow_ack_time))
return;
/* Then check host-wide RFC 5961 rate limit. */
now = jiffies / HZ;
if (now != READ_ONCE(nip_challenge_timestamp)) {
u32 ack_limit = READ_ONCE(net->ipv4.sysctl_tcp_challenge_ack_limit);
u32 half = (ack_limit + 1) >> 1;
WRITE_ONCE(nip_challenge_timestamp, now);
WRITE_ONCE(nip_challenge_count, half + prandom_u32_max(ack_limit));
}
count = READ_ONCE(nip_challenge_count);
if (count > 0) {
WRITE_ONCE(nip_challenge_count, count - 1);
NET_INC_STATS(net, LINUX_MIB_TCPCHALLENGEACK);
tcp_nip_send_ack(sk);
}
}
static int tcp_nip_ack(struct sock *sk, const struct sk_buff *skb, int flag)
{
struct tcp_sock *tp = tcp_sk(sk);
struct tcp_nip_common *ntp = &tcp_nip_sk(sk)->common;
@@ -1579,8 +1628,15 @@ static int tcp_nip_ack(struct sock *sk, const struct sk_buff *skb)
int prior_packets = tp->packets_out;
ktime_t skb_snd_tstamp = 0;
if (before(ack, prior_snd_una))
if (before(ack, prior_snd_una)) {
if (before(ack, prior_snd_una - tp->max_window)) {
if (!(flag & FLAG_NO_CHALLENGE_ACK))
tcp_nip_send_challenge_ack(sk, skb);
return -1;
}
return 0;
}
if (after(ack, tp->snd_nxt))
return -1;
@@ -1737,7 +1793,7 @@ void tcp_nip_rcv_established(struct sock *sk, struct sk_buff *skb,
if (!tcp_nip_validate_incoming(sk, skb, th, 1))
return;
if (tcp_nip_ack(sk, skb) < 0)
if (tcp_nip_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0)
goto discard;
tcp_nip_data_queue(sk, skb);
@@ -1867,7 +1923,7 @@ static int tcp_nip_rcv_synsent_state_process(struct sock *sk, struct sk_buff *sk
tcp_init_wl(tp, TCP_SKB_CB(skb)->seq);
tcp_nip_ack(sk, skb);
tcp_nip_ack(sk, skb, FLAG_SLOWPATH);
tp->out_of_order_queue = RB_ROOT;
/* The next data number expected to be accepted is +1 */
tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
@@ -1996,7 +2052,9 @@ int tcp_nip_rcv_state_process(struct sock *sk, struct sk_buff *skb)
if (!tcp_nip_validate_incoming(sk, skb, th, 0))
return 0;
acceptable = tcp_nip_ack(sk, skb);
acceptable = tcp_nip_ack(sk, skb, FLAG_SLOWPATH |
FLAG_UPDATE_TS_RECENT |
FLAG_NO_CHALLENGE_ACK) > 0;
/* If the third handshake ACK is invalid, 1 is returned
* and the SKB is discarded in tcp_nip_rcv
*/