LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (https://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   TCP ACKs in kernel code (https://www.linuxquestions.org/questions/linux-kernel-70/tcp-acks-in-kernel-code-720414/)

rrbarbosa 04-20-2009 09:29 AM

TCP ACKs in kernel code
 
Hello,

I am interested in two points of TCP implementation for kernel 2.6.

The first point is about the 'quickack mode' used to make the congestion window to grow faster during the 'slow-start' phase. The code on tcp_input.c shows that number of quick acks to be sent is equal to the half of the receiver window worth of packets:

tcp_input.c/tcp_incr_quickack
Code:

unsigned quickacks = tp->rcv_wnd/(2*tp->ack.rcv_mss);
Is the value of rcv_wnd is always equal to the value of advertised window sent in a TCP segment? More precisely, is it possible to know (aprox.) how many quick acks are scheduled to be sent by looking a network trace (i.e. tcpdump)?

The second point is that I understood that the linux implementation can send a delayed ack for more than two packets as the delayed ack mechanism is not based on the number of packets, but in the 'ato' (ack time out?!). And thus *not* following recommendation the RFC 2581 ("The requirement that an ACK "SHOULD" be generated for at least every second full-sized segment..."). Which is OK, as it is a SHOULD.

What I cannot understand is how the timer is controlled. I do not understand how "about to expire" is tested on the code bellow:

tcp_output.c/tcp_send_delayed_ack
Code:

/* If delack timer was blocked or is about to expire,
* send ACK now.
*/
if (tp->ack.blocked || time_before_eq(tp->ack.timeout, jiffies+(ato>>2))) {
        tcp_send_ack(sk);
        return;
}

Can somebody help me with those?

Thanks,
Rafael

Mara 04-24-2009 03:34 PM

Question 1: IMO not always. There's window scalling possible. For details look into tcp_output.c: tcp_select_window

Question 2: This piece of code sends the ack if it's not worth it to set a timer, because the time is too close. ato will usually be HZ/25. So ato/4 is HZ/100. Really short period of time :)

rrbarbosa 05-22-2009 07:13 AM

Quote:

Originally Posted by Mara (Post 3519934)
Question 1: IMO not always. There's window scalling possible. For details look into tcp_output.c: tcp_select_window

Question 2: This piece of code sends the ack if it's not worth it to set a timer, because the time is too close. ato will usually be HZ/25. So ato/4 is HZ/100. Really short period of time :)

Thanks for the answer. Regarding question 2, ato/4 (1ms?) is not a so short period of time... but I understand the test now.

I've been working in other stuff for a while but now I back on the TCP code. Still trying to understand how ACKs are sent. I think I got most of it figured out. There is a part that I do not quite understand though.

On tcp_input.c , one ack is generated imediatelly in 3 cases by __tcp_ack_snd_check :

Code:

            /* More than one full frame received... */
        if (((tp->rcv_nxt - tp->rcv_wup) > 
                          inet_csk(sk)->icsk_ack.rcv_mss
              /* ... and right edge of window advances far enough.
              * (tcp_recvmsg() will send ACK otherwise). Or...
              */
              && __tcp_select_window(sk) >= tp->rcv_wnd) ||
            /* We ACK each frame or... */
            tcp_in_quickack_mode(sk) ||
            /* We have out of order data. */
            (ofo_possible && skb_peek(&tp->out_of_order_queue))) {
                /* Then ack it now */
                tcp_send_ack(sk);

The second and third options are clear, quick ack mode and out of order data. But I do not quite understand the first.

- What it means to receive a packet larger than the MSS?
- My understanding is that
Code:

__tcp_select_window(sk) >= tp->rcv_wnd
tests if the receiver window is going to grow. Is that correct?
- Summarizing, what is the first option testing??

Thanks,
Rafael


All times are GMT -5. The time now is 09:35 PM.