Learning the Linux kernel tracking function sys_listen

Source: Internet
Author: User

Asmlinkage long sys_socketcall (INT call, unsigned long _ User * ARGs );

{
Unsigned long a [6];
/* Obtain information from the user space. This function is SMP secure */
If (copy_from_user (A, argS, nargs [Call])
Return-efault;

Switch (CALL ){
Case sys_socket:
Err = sys_socket (A [0], a [1], a [2]);
Break;
Case sys_bind:
Err = sys_bind (A [0], (struct sockaddr _ User *) A [1], a [2]);
Break;
Case sys_connect:
Err = sys_connect (A [0], (struct sockaddr _ User *) A [1], a [2]);
Break;

....
}
}

/*
* The following describes the sys_listen function.
*
* This function first calls the sockfd_lookup_light function,
* Obtain the struct file * file structure with the descriptor Based on the descriptor, and then obtain the struct socket * sock structure based on the file structure.
* Get FD and backlog from user space
* Call the sock-> OPS-> listen () function, which is inet_listen [net/IPv4/af_inet.c] in TCP.
* For UDP, sock-> OPS-> Listen = sock_no_listen is returned directly.
*/

Asmlinkage long sys_listen (int fd, int backlog)
{
Struct socket * sock;
Int err, fput_needed;

/*
* Find the struct socket * sock structure with this descriptor
*/
Sock = sockfd_lookup_light (FD, & err, & fput_needed );
If (sock ){
If (unsigned) Backlog> sysctl_somaxconn)
Backlog = sysctl_somaxconn;
/*
* Sock-> Ops = & inet_stream_ops | & inet_dgram_ops,
*
* TCP: sock-> OPS-> Listen = inet_listen
* UDP: sock-> OPS-> Listen = sock_no_listen
*/
Err = sock-> OPS-> listen (sock, backlog );

Fput_light (sock-> file, fput_needed );
}
Return err;
}

/*
* In the inet_listen function, first determine whether the sock status is ss_unconnected and whether the type is sock_stream. If not, exit directly.
* Then judge whether the sock-> SK is in the listened status. If yes, set the backlog directly and exit.
* Otherwise, call inet_csk_listen_start [net/IPv4/inet_connection_sock.c].
*/
Int inet_listen (struct socket * sock, int backlog)
{
Struct sock * Sk = sock-> SK;
Unsigned char old_state;
Int err;

Lock_sock (SK );

Err =-einval;
If (sock-> state! = Ss_unconnected | sock-> type! = Sock_stream)
Goto out;

Old_state = Sk-> sk_state;
If (! (1 <old_state) & (tcpf_close | tcpf_listen )))
Goto out;

/* Really, if the socket is already in listen state
* We can only allow the backlog to be adjusted.
*/
If (old_state! = Tcp_listen ){
Err = inet_csk_listen_start (SK, backlog );
If (ERR)
Goto out;
}
SK-> sk_max_ack_backlog = backlog;
Err = 0;

Out:
Release_sock (SK );
Return err;
}

/*
* Inet_csk_listen_start [net/IPv4/inet_connection_sock.c]
* This function first calls reqsk_queue_alloc [net/CORE/request_sock.c] To apply for a piece of memory and store the listener queue for accept;
* Set the listening status and put the struct sock * SK into tcp_hashinfo.ehash.
*/

Int inet_csk_listen_start (struct sock * SK, const int nr_table_entries)
{
Struct inet_sock * Inet = inet_sk (SK );
Struct inet_connection_sock * icsk = inet_csk (SK );
Int rc = reqsk_queue_alloc (& icsk-> icsk_accept_queue, nr_table_entries );

If (RC! = 0)
Return RC;

SK-> sk_max_ack_backlog = 0;
SK-> sk_ack_backlog = 0;
/*
* Only memset
* Memset (& inet_csk (SK)-> icsk_ack, 0, sizeof (inet_csk (SK)-> icsk_ack ));
*/
Inet_csk_delack_init (SK );

/*
* Set the listening status and determine whether the port is not used
* Add it to tcp_hashinfo.ehash.
* Return 0;
*/
SK-> sk_state = tcp_listen;
If (! SK-> sk_prot-> get_port (SK, iNet-> num )){
INet-> sport = htons (iNet-> num );

Sk_dst_reset (SK );
SK-> sk_prot-> Hash (SK );

Return 0;
}

SK-> sk_state = tcp_close;
_ Reqsk_queue_destroy (& icsk-> icsk_accept_queue );
Return-eaddrinuse;
}

A comprehensive website for Linux application development, www.linuxhao.com, and www.linuxhao.com provides Linux video tutorials, Linux training courses, and Linux technical materials for free.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.