TCP socket系统调用实现源码分析

系统调用入口:

int __sys_socket(int family, int type, int protocol)// net/socket.c
{
	retval = sock_create(family, type, protocol, &sock);//
	if (retval < 0)
		return retval;

	return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
}

第一个函数:

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函数:

int __sock_create(struct net *net, int family, int type, int protocol,
			 struct socket **res, int kern)
{
err = pf->create(net, sock, protocol, kern);
}

pf->create:

// 对于ipv6
static const struct net_proto_family inet6_family_ops = { // net/ipv6/af_inet6.c
    .family = PF_INET6,
    .create = inet6_create,
    .owner  = THIS_MODULE,
};
static int inet6_create(struct net *net, struct socket *sock, int protocol,
			int kern)
{
	sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot, kern);// 创建sock 结构体

	if (inet->inet_num) {
		/* It assumes that any protocol which allows
		 * the user to assign a number at socket
		 * creation time automatically shares.
		 */
		inet->inet_sport = htons(inet->inet_num);
		err = sk->sk_prot->hash(sk);// hash:
		if (err) {
			sk_common_release(sk);
			goto out;
		}
	}
	if (sk->sk_prot->init) {
		err = sk->sk_prot->init(sk);// 
		if (err) {
			sk_common_release(sk);
			goto out;
		}
	}

}

继续 hash函数,把套接字管理起来!!!

struct proto tcpv6_prot = { // tcp_ipv6.c
...
.hash			= inet6_hash,
}
int inet6_hash(struct sock *sk)
{
...
		err = __inet_hash(sk, NULL);
...

继续:

int __inet_hash(struct sock *sk, struct sock *osk)
{
	struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
	struct inet_listen_hashbucket *ilb;
	int err = 0;

	if (sk->sk_state != TCP_LISTEN) {// 两种套接字,监听、已连接套接字。
		inet_ehash_nolisten(sk, osk);
		return 0;
	}
	WARN_ON(!sk_unhashed(sk));
	ilb = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];

	spin_lock(&ilb->lock);
	if (sk->sk_reuseport) {
		err = inet_reuseport_add_sock(sk, ilb);
		if (err)
			goto unlock;
	}
	if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport &&
		sk->sk_family == AF_INET6)
		hlist_add_tail_rcu(&sk->sk_node, &ilb->head);
	else
		hlist_add_head_rcu(&sk->sk_node, &ilb->head);
	inet_hash2(hashinfo, sk);
	ilb->count++;
	sock_set_flag(sk, SOCK_RCU_FREE);
	sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
unlock:
	spin_unlock(&ilb->lock);

	return err;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值