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?