您的位置:首页 > 运维架构 > Linux

How Linux kernel handles the send system call

2015-02-03 17:28 316 查看
This is a brief introduction about how Linux kernel handles the
send
system call.

This study is based on kernel version 3.7.2, which is the latest stable kernel when writing this study.


How
system call is defined

In the latest kernel, the system call is defined using the
SYSCALL_DEFINEx
macro, in which
x
is
the number of arguments. For example, in order to find the definition of
asmlinkage long sys_sendto(int, void __user *,
 size_t, unsigned, struct sockaddr __user *, int);
, you need to
grep
for
SYSCALL_DEFINE6
because
it has 6 arguments.

The definition of the system call
send
can be found at
net/socket.c
.


How
is the
send
system call handled


Definition
of
send
system call

Here's the code of the
send
system call
[code]/*
 *  Send a datagram down a socket.
 */
SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
        unsigned int, flags)
{
    return sys_sendto(fd, buff, len, flags, NULL, 0);
}


From the code we know that the
send
system call is just a simple wrapper function around another system call
sendto
.


Definition
of
sendto
system call

The definition of
sendto
system call is available in the same file,
net/socket.c
.
[code]/*
 *  Send a datagram to a given address. We move the address into kernel
 *  space and check the user space data area is readable before invoking
 *  the protocol.
 */
SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
        unsigned int, flags, struct sockaddr __user *, addr,
        int, addr_len)


Here's the definition of each argument from
man 2 sendto
:

int fd
: the file descriptor of the socket, which is used to send the data to
void __user * buff
: the content which will be send by this system call
size_t len
: the length of the
buff

unsigned int flags
: the bitwise OR of some predefined constants
struct sockaddr __user * addr
: the destination address. The
send
system
call will set it to NULL
int addr_len
: the length of the
addr
struct,
which
send
system call will set it to zero

Here's the description about
sendto
's behaviour:

use
sockfd_lookup_light
to find the corresponding socket descriptor
and return it
This function will try to valid if the provided integer
fd
is a valid
file descriptor, then return the sockeet if it's valid, otherwise return
NULL
.

The message to be send will be assembled, then
sock_sendmsg
will
be called to send the message, whose return value will be returned by
sendto
then returned to
send
callee.


Definition
of
sock_sendmsg
call

Below is the description of the
sock_sendmsg
function call

call
init_sync_kiocb
, which just inited a new
kiocb
struct.
kiocb
is
used as callback if the current system call is asynchronous.

call
__sock_sendmsg
, which is a wrapper around
security_socket_sendmsg
and
__sock_sendmsg_nosec
.
The kernel will try to call
security_socket_sendmsg
to check the
permission before transmitting, and then call
__sock_sendmsg_nosec
to send it.
Function
__sock_sendmsg_nosec
will call
sock->ops->sendmsg
to
send the message
The
socket->ops
is a
proto_ops
,
which is a protocol-specific struct.


Definition
of
proto_ops
struct and its
sendmsg
function

This is a protocol-specific. Depending on the socket type (IPv6/IPv4, UDP/TCP/RAW), there's different implementation of this struct.

For most socket types (at least for IPv4+TCP, IPv4+UDP, IPv4+RAW), the
inet_sendmsg
function will be called to sendmsg.

In function
inet_sendmsg
, if the current socket is not
bind
ed,
kernel will call
inet_autobind
to bind the socket to a local IP/port.

In
inet_sendmsg
, it will call
socket->sk_prot->sendmsg
.
We finally reach the transport layer -> internet layer interface.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: