想研究下linux的recv是怎么实现的,写了一半

本文通过分析Linux源码,逐步揭示了recv函数的工作原理。从在源码中寻找recv函数开始,发现其实际调用了kernel_recvmsg,接着在net/socket.c中找到了kernel_recvmsg的实现,它进一步调用了sock_recvmsg。接着,文章探讨了security_socket_recvmsg在安全层面的角色,该函数检查接收消息的权限。最后,介绍了security_ops结构体及其在安全操作中的重要性。

1、

在linux源码中查找

find | /bin/grep sock| xargs  /bin/grep “ recv(“

查找recv函数,空格隔开,过滤了_recv之类的。

没有找到recv的函数定义。

 

放宽条件,在./fs/ncpfs/sock.c中找到了

 

static int _recv(struct socket *sock, void*buf, int size, unsignedflags)

{

     struct msghdr msg = {NULL, };

     struct kvec iov = {buf, size};

     return kernel_recvmsg(sock, &msg, &iov, 1,size, flags);

}

调用kernel_recvmsg

 

2、找kernel_recvmsg

在./net/socket.c中找到,

/**

 * kernel_recvmsg - Receive a message from asocket (kernel space)

 * @sock:      The socket to receive the message from

 * @msg:       Received message

 * @vec:       Input s/g array for message data

 * @num:       Size of input s/g array

 * @size:      Number of bytes to read

 * @flags:     Message flags (MSG_DONTWAIT, etc...)

 *

 * On return the msg structure contains thescatter/gather array passed in the

 * vec argument. The array is modified so thatit consists of the unfilled

 * portion of the original array.

 *

 * The returned value is the total number ofbytes received, or an error.

 */

int kernel_recvmsg(structsocket *sock, struct msghdr *msg,

            struct kvec*vec, size_t num, size_t size, int flags)

{

     mm_segment_toldfs = get_fs();

     int result;

 

     set_fs(KERNEL_DS);

     /*

      * the following is safe,since for compiler definitions of kvec and

      * iovec are identical,yielding the same in-core layout and alignment

      */

     msg->msg_iov= (struct iovec *)vec, msg->msg_iovlen =num;

     result= sock_recvmsg(sock, msg, size, flags);

     set_fs(oldfs);

     return result;

}

EXPORT_SYMBOL(kernel_recvmsg);

 

3、找sock_recvmsg(),与kernel_recvmsg一样,还是在./net/socket.c

 

static inline int __sock_recvmsg(structkiocb *iocb, struct socket *sock,

                    struct msghdr*msg, size_t size, int flags)

{

     int err = security_socket_recvmsg(sock, msg, size,flags);

 

     return err ?: __sock_recvmsg_nosec(iocb, sock, msg,size, flags);

}

 

int sock_recvmsg(structsocket *sock, struct msghdr *msg,

          size_t size, intflags)

{

     struct kiocb iocb;

     struct sock_iocb siocb;

     int ret;

 

     init_sync_kiocb(&iocb,NULL);

     iocb.private = &siocb;

     ret= __sock_recvmsg(&iocb, sock, msg, size, flags);

     if (-EIOCBQUEUED == ret)

         ret= wait_on_sync_kiocb(&iocb);

     return ret;

}

EXPORT_SYMBOL(sock_recvmsg);

调用的是security_socket_recvmsg(

 

4、security_socket_recvmsg()在./security/ security.c中

int security_socket_recvmsg(structsocket *sock, struct msghdr *msg,

                  int size, int flags)

{

     return security_ops->socket_recvmsg(sock, msg,size, flags);

}

找security_ops这个结构在哪里定义。

 

5 security_ops这个结构在security.h中定义,这里定义了很多的操作,

* @socket_sendmsg:

 *   Checkpermission before transmitting a message to another socket.

 *   @sockcontains the socket structure.

 *   @msgcontains the message to be transmitted.

 *   @sizecontains the size of message.

 *   Return0 if permission is granted.

 * @socket_recvmsg:

 *   Checkpermission before receiving a message from a socket.

 *   @sockcontains the socket structure.

 *   @msgcontains the message structure.

 *   @sizecontains the size of message structure.

 *   @flagscontains the operational flags.

 *   Return0 if permission is granted.

struct security_operations {

     char name[SECURITY_NAME_MAX + 1];

 

     int (*ptrace_access_check) (structtask_struct *child, unsigned int mode);

     int (*ptrace_traceme) (structtask_struct *parent);

     int (*capget) (structtask_struct *target,

                kernel_cap_t *effective,

                kernel_cap_t *inheritable, kernel_cap_t*permitted);

省略300个以上的函数,包括建立inode、建立目录等等很多操作系统的底层操作,可以详细研究本结构

#ifdef CONFIG_SECURITY_NETWORK

     int (*unix_stream_connect) (structsock *sock, struct sock *other, struct sock *newsk);

     int (*unix_may_send) (structsocket *sock, struct socket *other);

 

     int (*socket_create) (intfamily, int type, intprotocol, int kern);

     int (*socket_post_create) (structsocket *sock, int family,

                      int type, int protocol, intkern);

     int (*socket_bind) (structsocket *sock,

                  structsockaddr *address, int addrlen);

     int (*socket_connect) (structsocket *sock,

                     structsockaddr *address, int addrlen);

     int (*socket_listen) (structsocket *sock, int backlog);

     int (*socket_accept) (structsocket *sock, struct socket *newsock);

     int (*socket_sendmsg) (structsocket *sock,

                     structmsghdr *msg, int size);

     int (*socket_recvmsg) (struct socket*sock,

                     structmsghdr *msg, int size, intflags);

     int (*socket_getsockname) (structsocket *sock);

     int (*socket_getpeername) (structsocket *sock);

     int (*socket_getsockopt) (structsocket *sock, int level, int optname);

     int (*socket_setsockopt) (structsocket *sock, int level, int optname);

     int (*socket_shutdown) (structsocket *sock, int how);

     。。。。。。。。省50个函数

#endif   /* CONFIG_SECURITY_NETWORK */

};

 

 

security.h中security_ops结构的定义之外还有很多security_ops结构中用到的函数定义。

。。。。

int security_socket_listen(structsocket *sock, int backlog);

int security_socket_accept(structsocket *sock, struct socket *newsock);

int security_socket_sendmsg(structsocket *sock, struct msghdr *msg, int size);

int security_socket_recvmsg(structsocket *sock, struct msghdr *msg,

                  int size, int flags);

。。。

 

内联函数再实现一遍

static inline int security_socket_recvmsg(structsocket *sock,

                         struct msghdr*msg, int size,

                         int flags)

{

     return 0;

}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值