Thursday, January 27, 2011

網路Driver 2- Linux内核网络源码分析——建立套接字

Linux内核网络源码分析——建立套接字

目录:Linux内核网络源码分析
socket()
user
————————————————–
kernel

sys_socketcall() <net/socket.c>
asmlinkage long sys_socketcall(int call, unsigned long __user *args)
    …
    case SYS_SOCKET:
    err = sys_socket(a0, a1, a[2]);
    break;
    …
sys_socket() <net/socket.c>
asmlinkage long sys_socket(int family, int type, int protocol)

retval = sock_create(family, type, protocol, &sock);

retval = sock_map_fd(sock);
//为套接字分配一个文件描述符并分配一个file文件,
//在应用层可象处理文件一样处理套接字了。

sock_create() <net/socket.c>
int sock_create(int family, int type, int protocol, struct socket **res)
{
return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
// current宏用于获取当前进程的task_struct
}
__sock_create()
static int __sock_create(struct net *net, int family, int type, int protocol,
struct socket **res, int kern)

pf = rcu_dereference(net_families[family]);//获取net_proto_family结构

err = pf->create(net, sock, protocol);
// 使用net_proto_family的create函数构建BSD Socket
// 当family为AF_INET时,调用的是inet_create


inet_create() <net/ipv4/af_inet.c> //Create an inet socket
static int inet_create(struct net *net, struct socket *sock, int protocol)

sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot);
// 根据指定协议为sock分配内存空间,并初始化

if (sk->sk_prot->init) {
err = sk->sk_prot->init(sk);//调用协议(struct proto)指定的初始化函数

// 如果类型是SOCK_STREAM的话会调用tcp_v4_init_sock,
// 而SOCK_DGRAM类型的socket没有额外的初始化了,到此socket调用结束
// 参见:

inet_init() <net/ipv4/af_inet.c:>
static struct inet_protosw inetsw_array[] <net/ipv4/af_inet.c:>
struct proto tcp_prot={…} <net/ipv4/tcp_ipv4.c>
struct proto udp_prot={…} <net/ipv4/udp.c>


This entry was posted in Software Development. Bookmark the permalink.

No comments:

Post a Comment