当前位置:网站首页>When to send the update windows message
When to send the update windows message
2022-06-24 21:24:00 【already_ skb】
* then send an ACK if necessary. COPIED is the number of bytes
* tcp_recvmsg has given to the user so far, it speeds up the
* calculation of whether or not we must ACK for the sake of
* a window update.
*/
static void tcp_cleanup_rbuf(struct sock *sk, int copied)
{
struct tcp_sock *tp = tcp_sk(sk);
bool time_to_ack = false;
struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq),
"cleanup rbuf bug: copied %X seq %X rcvnxt %X\n",
tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt);
if (inet_csk_ack_scheduled(sk)) {
const struct inet_connection_sock *icsk = inet_csk(sk);
/* Delayed ACKs frequently hit locked sockets during bulk
* receive. */
if (icsk->icsk_ack.blocked ||
/* Once-per-two-segments ACK was not sent by tcp_input.c */
tp->rcv_nxt - tp->rcv_wup > icsk->icsk_ack.rcv_mss ||
/*
* If this read emptied read buffer, we send ACK, if
* connection is not bidirectional, user drained
* receive buffer and there was a small segment
* in queue.
*/
(copied > 0 &&
((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) ||
((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) &&
!icsk->icsk_ack.pingpong)) &&
!atomic_read(&sk->sk_rmem_alloc)))
time_to_ack = true;
}
/* We send an ACK if we can now advertise a non-zero window
* which has been raised "significantly".
*
* Even if window raised up to infinity, do not send window open ACK
* in states, where we will not receive more. It is useless.
*/
if (copied > 0 && !time_to_ack && !(sk->sk_shutdown & RCV_SHUTDOWN)) {
__u32 rcv_window_now = tcp_receive_window(tp);
/* Optimize, __tcp_select_window() is not cheap. */
if (2*rcv_window_now <= tp->window_clamp) {
__u32 new_window = __tcp_select_window(sk);
/* Send ACK now, if this read freed lots of space
* in our buffer. Certainly, new_window is new window.
* We can advertise it now, if it is not less than current one.
* "Lots" means "at least twice" here.
*/
if (new_window && new_window >= 2 * rcv_window_now)
time_to_ack = true;
}
}
if (time_to_ack)
tcp_send_ack(sk);
}
边栏推荐
- How Fiddler works
- 网络安全审查办公室对知网启动网络安全审查
- Handling of garbled JMeter response data - three solutions
- TCP specifies the source port
- Foundations of Cryptography
- Distributed basic concepts
- I just purchased a MySQL database and prompted that there are already instances. The console login instance needs to provide a database account. How do I know the database account.
- Several common command operations in win system
- Typescript syntax
- yeb_ Back first day
猜你喜欢

Dynamic routing protocol rip, OSPF

The Google File System (GFS) learning notes

It was Tencent who jumped out of the job with 26k. It really wiped my ass with sandpaper. It gave me a hand

Arkit与Character Creator动画曲线的对接

Background of master data construction

How to apply agile development ideas to other work

Pod lifecycle in kubernetes

Background operation retry gave up; KeeperErrorCode = ConnectionLoss

What does CTO (technical director) usually do?

大厂出海,败于“姿态”
随机推荐
memcached全面剖析–5. memcached的应用和兼容程序
CondaValueError: The target prefix is the base prefix. Aborting.
A/b test helps the growth of game business
Analysis of errors in JSON conversion using objectmapper
HCIA assessment
Basic database syntax learning
Does the developer want to change to software testing?
Learn together and make progress together. Welcome to exchange
Sleep revolution - find the right length of rest
JMeter parameterization
Curl command
Apple mobile phone can see some fun ways to install IPA package
Introduction to interval DP
Return of missing persons
Auto. JS to realize automatic unlocking screen
Network layer
Procedural life: a few things you should know when entering the workplace
Why do we always "give up halfway"?
yeb_ Back first day
Reflection - class object function - get method (case)