linux内核网络-使用协议族创建socket“每日读书“

我们回到__sock_create() 函数继续往下分析创建了socket以后代码11501153net_families[]数组检查对应family协议族操作有没有安装回忆服务器程序创建socket代码

server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

我们先不关心其他参数重点注意传递family参数AF_INET, 这个值定义为2这里也就是检查数组net_families[2] 是否安装了AF_INET协议组操作表当然也是内核初始化安装完成安装net/ipv4/af_inet.c 采用initcall 机制inet_init函数进行安装擦欧总从而完成AF_INET协议族操作注册

fs_initcall(inet_init)

fs_initcall 是一个定义它的定义include/linux/init.h

fs_initcallinet_init安装到了initcall因此Linux初始化会执行inet_init函数

static int __init inet_init(void)

(void)sock_register(&inet_family_ops);//安装协议族操作表

代码1426转入sock_register 完成注册

inet_init()->sock_register()

int sock_register(const struct net_proto_family *ops)

{

spin_lock(&net_family_lock);

if (net_families[ops->family])

err = - EEXIST;

else {

net_familys[p[s->family] = ops;//操作表登记全局数组

err = 0;

    }

}

2122 AF_INET协议操作结构inet_family_ops注册net_families数组中

这个操作结构定义/net/ipv4/af_inet.c

static struct net_proto_family inet_family_ops = {

.family = PF_INET,

.create = inet_create,

.owner = THIS_MODULE,

};

928family PF_INET就是AF_INET

#define PF_INET AF_INET

结构体net_proto_family内容比较简单在此就不列出找到协议族操作之后

_sock_create函数1169pf->create(net,sock,protocol)语句得以执行, 对照inet_family_ops结构create 钩子函数挂入inet_create()函数代码比较多因此分段分析

sys_socketcall()->sys_socket()->sock_create()->__sock_create()->inet_create()

static int inet_create(struct net *net, struct socket *sock, int protocol)

{

struct sock *sk;

struct list_head *p;

struct inet_protosw *anser;

struct inet_sock *inet;

struct proto *anser_prot;

unsigned char anwer_flags;

char answer_no_check;

int try_loading_module = 0;

int err;

//检查SOCKET类型加密字符

if (sock->type != SOCK_RAM &&

sock->type != SOCK_DGRAM && !inet_ehash_secret) build_ehash_secret()

sock->state = SS_UNCONNECTED;

answer = NULL;

}

前面__sock_create() 函数1140服务器程序设置类型赋值给了分配sock从而sock设置成了SOCK_STREAM, 数据流类型这里首先检查sock类型查看是否SOCK_RAWSOCK_DGRAM 类型socket并且判断是否已经有了加密字符如果没有就会在282调用build_ehash_secret()

设置.

sys_sockcall()->sys_socket->sock_create->sock_create_inet_create

void build _ehash_secret(void)

{

u32 rnd;

do {//获得随机数

get_random_bytes(&rnd, sizeof(rnd));

    }while(rnd == 0);

spin_lock_bh(&inetsw_lock);

if (!inet_ehash_secret)

inet_ehash_secret = rnd; //使用随机数作为加密字符

spin_unlock_bh(&inetsw_lock);

}

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值