内核中的UDP socket流程(3)——sock_create
作者:gfree.wind@gmail.com
由于种种原因,工作的,私人的,学习停了几天。周末的时候,一天生病,还把《让子弹飞》和《非常勿扰2》看了。这两个片子还真火,几乎满座啊。非2远没有子弹好看,甚至还不如虎头蛇尾的《赵氏孤儿》呢。
好了,闲话少说。上次看到了sys_socket调用sock_create的地方了。下面开始研究sock_create了。
sys_socket将自己的参数family, type, protocol传给sock_create,而sock为sock_create的输出值。
retval = sock_create(family, type, protocol, &sock); |
下面看sock_create的代码
int sock_create(int family, int type, int protocol, struct socket **res) { return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0); }
|
sock_create不过是一个包装函数,它通过__sock_create真正的去创建socket。
其中,current是当前task的指针——实际上current是一个宏,这个宏在linux内核中已经存在很久了。task的类型为struct task_struct。nsproxy是它的一个成员变量,是task的命名空间指针,下面是它的定义:
struct nsproxy { atomic_t count; struct uts_namespace *uts_ns; struct ipc_namespace *ipc_ns; struct mnt_namespace *mnt_ns; struct pid_namespace *pid_ns; struct net *net_ns; }; |
与咱们有关的就是最后一个指针,net_ns。命名空间namespace是linux在2.6中引入的特性,是为了虚拟化而做的。具体定义可以参考
http://oldwiki.linux-vserver.org/Namespaces
uts_ns: UTS命名空间包含了运行内核的名称、版本、底层体系机构类型等信息。UTS是UNIX Timesharing System的缩写;
ipc_ns:保存所有与进程通信(IPC)有关的信息
mnt_ns:保存已mount的文件系统信息;
pid_ns:有关进程ID的信息;
net_ns:这是与咱们有关的,包含所有网络相关的命名空间。
这是第一个参数。
最后一个参数,则表明这个创建的socket是否为kernel层创建的。对于我们来说,这个socket是为应用层创建的,所有最后一个参数是0.
下面开始分析__sock_create
static int __sock_create(struct net *net, int family, int type, int protocol, struct socket **res, int kern) { int err; struct socket *sock; const struct net_proto_family *pf;
/* * Check protocol is in range */ if (family 0 || family >= NPROTO) return -EAFNOSUPPORT; if (type 0 || type >= SOCK_MAX) return -EINVAL; /* * Skip some codes */ } |
首先这个函数,先对family和type进行检查,查看是否超出正常范围。
唉,又12点了,明天再见了!