Hello everyone,recently I am looking at the source code for handling TCP 
three-way handshake(Linux Kernel version 4.18.5).

I found some strange places in the source code for handling syn messages.

in the function "tcp_conn_request"

This code will be executed when we don't enable the syn cookies.

                if (!net->ipv4.sysctl_tcp_syncookies &&
                    (net->ipv4.sysctl_max_syn_backlog - 
inet_csk_reqsk_queue_len(sk) <
                     (net->ipv4.sysctl_max_syn_backlog >> 2)) &&
                    !tcp_peer_is_proven(req, dst)) {
                        /* Without syncookies last quarter of
                         * backlog is filled with destinations,
                         * proven to be alive.
                         * It means that we continue to communicate
                         * to destinations, already remembered
                         * to the moment of synflood.
                         */
                        pr_drop_req(req, ntohs(tcp_hdr(skb)->source),
                                    rsk_ops->family);
                        goto drop_and_release;
                }

But why don't we use all the syn queues?

Why do we need to leave the size of (net->ipv4.sysctl_max_syn_backlog >> 2) in 
the queue?

Even if the system is attacked by a syn flood, there is no need to leave a 
part. Why do we need to leave a part?

The value of sysctl_max_syn_backlog is the maximum length of the queue only if 
syn cookies are enabled.


This is the first strange place, here is another strange place

        __u32 isn = TCP_SKB_CB(skb)->tcp_tw_isn;

        if ((net->ipv4.sysctl_tcp_syncookies == 2 ||
             inet_csk_reqsk_queue_is_full(sk)) && !isn) {

        if (!want_cookie && !isn) {

The value of "isn" comes from TCP_SKB_CB(skb)->tcp_tw_isn, then it is judged 
twice whether its value is indeed 0.

But "tcp_tw_isn" is initialized in the function "tcp_v4_fill_cb"

        TCP_SKB_CB(skb)->tcp_tw_isn = 0;

So it has always been 0, I used printk to test, and the result is always 0.

Since it is always 0, why do you need to judge twice?

This is two strange places I found.

Can anyone tell me why the code here is written like this?


Reply via email to