注册协议操作集

来源:互联网 发布:小站雅思app电脑版mac 编辑:程序博客网 时间:2024/05/21 07:15


   前面讲到,在数组inetsw_array中有INET域支持的全部套接字类型和协议类型,在一个结构体struct inet_protosw中,记录了一个套接字类型,该类型下的一种协议类型,以及该类型套接字的操作集和该类型协议的操作集,对于原始套接字,其协议类型为通配类型,通配所有网络层附属协议,其协议操作集为所有网络层附属协议的通过协议操作集,即struct proto raw_prot。在INET域进行初始化的时候,其要做的第一件事情就是通过函数proto_register注册协议操作集。
    struct proto的成员slab是一个后备高速缓冲区,所有该类型下的网络层套接字struct sock都是从该后备高速缓冲区分配内存,struct proto的成员obj_size记录的是单个网络层套接字的空间大小,供分配slab时使用,其值是sizeof(struct raw_sock),raw_sock是对inet_sock的一个扩充(inet_sock是对sock的扩充)。在inet_create创建套接字的时候,调用sk_alloc创建struct sock,该函数直接从slab中分配内存。proto_register要做的第一件事情就是创建slab,struct proto还有成员rsk_prot和twsk_prot需要分配内存,也要在proto_register函数中完成,它是TCP协议相关的,暂时不关注。
    struct proto还有一个成员node,供proto_register把它插入到一个链表proto_list中。所有的协议操作集组织成一个链表放在一起。
    对原始套接字来讲,协议操作集中剩下的内容就是所有的操作函数了。
    struct inet_sock是INET域对struct sock的扩充。对于原始套接字类型,inet_sock的成员num置为协议类型,而struct raw_sock是对inet_sock的扩充,是完整意义上的原始套接字,定义如下:
    struct raw_sock {
        struct inet_sock   inet;
        struct icmp_filter filter;
    };
    struct proto raw_prot的raw_init函数判断如果inet_sock->num的值是IPPROTO_ICMP,则为filter清零。
    所有由应用程序创建出来的原始套接字需要一个统一的管理(内核创建的原始套接字不需要这种统一管理),raw_v4_htable就是这样一个实现统一管理的哈希表,它共有256项,所有的原始套接字,以它们的协议号(IPPROTO_ICMP,IPPROTO_IGMP等)作为索引,被创建后,都自动放到这个哈希表中,被放到哈项表同一项的套接字以链表的形式组织在一起。struct proto raw_prot的成员函数raw_v4_hash, raw_v4_unhash就是完成将套接字插入到哈希表中,和把套接字从哈希表中删除的工作。
    以上三个成员函数是在创建原始套接字时就会被调用到的,接下来还有其它的成员函数,后续会有陆续的分析介绍。
原创粉丝点击