2007年5月18日 星期五

socket receive api call 的運作流程

socket receive api call

Receiving packets
case SYS_RECV:
err = sys_recv(a0, (void __user *)a1, a[2], a[3]);

case SYS_RECVFROM:
err = sys_recvfrom(a0, (void __user *)a1, a[2], a[3], (struct sockaddr __user *)a[4], (int __user *)a[5]);

case SYS_RECVMSG:
/* BSD recvmsg interface */
err = sys_recvmsg(a0, (struct msghdr __user *) a1, a[2]);



Sending packets
case SYS_SEND:
err = sys_send(a0, (void __user *)a1, a[2], a[3]);

case SYS_SENDTO:
err = sys_sendto(a0,(void __user *)a1, a[2], a[3], (struct sockaddr __user *)a[4], a[5]);

case SYS_SENDMSG:
err = sys_sendmsg(a0, (struct msghdr __user *) a1, a[2]);


sys_recv

asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags)
{
return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
}


asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags,
struct sockaddr __user *addr, int __user *addr_len)
{
[略]
// main function
err=sock_recvmsg(sock, &msg, size, flags);
[略]
}


asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags)
{
[略]
err = sock_recvmsg(sock, &msg_sys, total_len, flags);
[略]
}

/*
all the received api will call sock_recvmsg function finally
*/
int sock_recvmsg(struct socket *sock, struct msghdr *msg,
size_t size, int flags)
{
[略]
ret = __sock_recvmsg(&iocb, sock, msg, size, flags);
[略]
}


static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)
{
[略]
err = security_socket_recvmsg(sock, msg, size, flags);
if (err)
return err;

return sock->ops->recvmsg(iocb, sock, msg, size, flags);
}

The Received API was followed the below line sequence
sock_recvmsg
__sock_recvmsg
sock->ops->recvmsg(iocb, sock, msg, size, flags);
/* This will issue sock_common_recvmsg function
* and then issue sk->sk_prot->recvmsg function
* For tcp it is the tcp_recvmsg
* then it is the tcp_prequeue_process
* teen if there is any packets exist in the prequeue buffer, run the sk->sk_backlog_rcv
* the sk->sk_backlog_rcv is a called back function (for tcp it is tcp_v4_do_rcv), which was
registered while the socket is created (inet_create function)
*/



sock->ops->recvmsg(iocb, sock, msg, size, flags);
will call
sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)

and then will call

sock->sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT,
flags & ~MSG_DONTWAIT, &addr_len);


In SOCK_STREAM will call the follwoing function

int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len, int nonblock, int flags, int *addr_len)


In SOCK_DGRAM will call the follwoing function

int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len, int noblock, int flags, int *addr_len)

In SOCK_RAW will call the follwoing function

int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len, int noblock, int flags, int *addr_len)

沒有留言: