Etapi listen () usage introduction, socketapilisten
0x02 API Introduction
Maximum length of a fully connected queue:
The backlog stores the three-way handshake and waits for the accept connection, instead of the semi-connection.
When the load is not high, the backlog does not need to be too large. (For complete connections)
The maximum number of unprocessed full connections in the system is min (backlog, somaxconn), and net. core. somaxconn is 128 by default.
This value is stored in sk-> sk_max_ack_backlog.
Maximum length of a semi-connection queue:
The default value of tcp_max_syn_backlog is 256. (For incomplete connections)
This parameter becomes invalid when SYN Cookie is used.
The maximum length of a semi-connection queue is the minimum value of backlog, somaxconn, and tcp_max_syn_backlog.
0x03 single-step tracking and analysis
3.1 SYSCALL_DEFINE2
/** System call Vector */SYSCALL_DEFINE2 (socketcall, int, call, unsigned long _ user *, args) {unsigned long a [6]; unsigned long a0, a1; int err; unsigned int len; if (call <1 | call> SYS_ACCEPT4) return-EINVAL; len = nargs [call]; if (len> sizeof ()) return-EINVAL;/* user space copy parameters */if (copy_from_user (a, args, len) return-EFAULT; audit_socketcall (nargs [call]/sizeof (unsigned long), a); a0 = a [0]; a1 = A [1];/* handle the status of socket-related calls based on the call subcall number. */Switch (call ){...... case SYS_LISTEN:/* a0 = 3, a1 = 20 is on the server. in the c code, set the same queue */err = sys_listen (a0, a1); break ;....... default: err =-EINVAL; break;} return err ;}
3.2 SYSCALL_DEFINE2 listen
SYSCALL_DEFINE2 (listen, int, fd, int, backlog) {struct socket * sock; int err, fput_needed; int somaxconn; sock = fig (fd, & err, & fput_needed ); if (sock) {/** [root @ B200-45 test] # sysctl-a | grep somaxconn * net. core. somaxconn = 128 */somaxconn = sock_net (sock-> sk)-> core. sysctl_somaxconn;/* if the backlog is greater than somaxconn, the default value is somaxconn. K you can adjust relevant parameters to increase the number of connections */if (unsigned) backlog> somaxconn) backlog = somaxconn;/* SELInux related */err = security_socket_listen (sock, backlog ); if (! Err)/* If tcp is used, call inet_listen */err = sock-> ops-> listen (sock, backlog ); /* put related parameters in */fput_light (sock-> file, fput_needed);} return err ;}
3.3inet _ listen
/* When the listener is started, the main tasks include: 1. Create an instance of the semi-connection queue and initialize the full-connection queue. 2. initialize some sock variables and set their status to TCP_LISTEN. 3. Check whether the port is available to prevent other processes from modifying the port information after bind. 4. Enter the sock link to the listening_hash listening hash table. */Int round (struct sock * sk, const int nr_table_entries) {struct inet_sock * inet = inet_sk (sk); struct inet_connection_sock * icsk = inet_csk (sk ); /* initialize the full-connection queue and create a semi-connection queue instance */int rc = reqsk_queue_alloc (& icsk-> icsk_accept_queue, nr_table_entries); if (rc! = 0) return rc;/* value * sk-> sk_max_ack_backlog = 0 when inet_listen () is returned; sk-> sk_ack_backlog = 0; /* icsk-> icsk_ack c initialization resetting */inet_csk_delack_init (sk);/* There is race window here: we announce ourselves listening, There is a competition window here: we declared that we were listening, but the transaction was still not verified by get_port. This is acceptable, because this socket enters the hash table only after verification is complete. */Sk-> sk_state = TCP_LISTEN;/* set the sock status to LISTEN */if (! Sk-> sk_prot-> get_port (sk, inet-> num) {inet-> sport = htons (inet-> num); // The Source Port sk_dst_reset (sk ); /* Add yourself to the ehash in tcp_hashinfo or listening_hash. This operation depends on the value of sk_state. If it is LISTEN, add it to the latter, if it is a value other than LISTEN, add it to the ehash table. We will see it in the code of connect. */Sk-> sk_prot-> hash (sk);/* link sock to the listener hash table */return 0;} sk-> sk_state = TCP_CLOSE; /* If the port is unavailable, release the semi-connection queue */_ reqsk_queue_destroy (& icsk-> icsk_accept_queue); return-EADDRINUSE ;}
0x04 Summary
The key parameter backlog emphasizes the configuration chart again: