Linux解析内核源代码—传输控制块诞生

发表于:2015-8-07 09:31

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:blfshiye    来源:51Testing软件测试网采编

  在Linux 2.6一旦(不包含2.6,对于更详细的调查是不是版本号),控制块的概念,各种协议的状态管理还出于比較混乱的状态。
  Linux 2.6以后。传输控制块机制使代码看起来比較规整了。
  创建传输控制块:
/*
*Create an inet socket.
*/
static int inet_create(struct socket *sock, int protocol)
{
struct sock *sk;
struct list_head *p;
struct inet_protosw *answer;
struct inet_opt *inet;
int err = -ENOBUFS;
sock->state = SS_UNCONNECTED;
sk = sk_alloc(PF_INET, GFP_KERNEL, inet_sk_size(protocol),
inet_sk_slab(protocol));
if (!sk)
goto out;
/* Look for the requested type/protocol pair. */
answer = NULL;
rcu_read_lock();
list_for_each_rcu(p, &inetsw[sock->type]) {
answer = list_entry(p, struct inet_protosw, list);
/* Check the non-wild match. */
if (protocol == answer->protocol) {
if (protocol != IPPROTO_IP)
break;
} else {
/* Check for the two wild cases. */
if (IPPROTO_IP == protocol) {
protocol = answer->protocol;
break;
}
if (IPPROTO_IP == answer->protocol)
break;
}
answer = NULL;
}
err = -ESOCKTNOSUPPORT;
if (!answer)
goto out_sk_free;
err = -EPERM;
if (answer->capability > 0 && !capable(answer->capability))
goto out_sk_free;
err = -EPROTONOSUPPORT;
if (!protocol)
goto out_sk_free;
err = 0;
sock->ops = answer->ops;
sk->sk_prot = answer->prot;
sk->sk_no_check = answer->no_check;
if (INET_PROTOSW_REUSE & answer->flags)
sk->sk_reuse = 1;
rcu_read_unlock();
inet = inet_sk(sk);
if (SOCK_RAW == sock->type) {
inet->num = protocol;
if (IPPROTO_RAW == protocol)
inet->hdrincl = 1;
}
if (ipv4_config.no_pmtu_disc)
inet->pmtudisc = IP_PMTUDISC_DONT;
else
inet->pmtudisc = IP_PMTUDISC_WANT;
inet->id = 0;
sock_init_data(sock, sk);
sk_set_owner(sk, THIS_MODULE);
sk->sk_destruct   = inet_sock_destruct;
sk->sk_zapped   = 0;
sk->sk_family   = PF_INET;
sk->sk_protocol   = protocol;
sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
inet->uc_ttl= -1;
inet->mc_loop= 1;
inet->mc_ttl= 1;
inet->mc_index= 0;
inet->mc_list= NULL;
#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet_sock_nr);
#endif
if (inet->num) {
/* It assumes that any protocol which allows
* the user to assign a number at socket
* creation time automatically
* shares.
*/
inet->sport = htons(inet->num);
/* Add to protocol hash chains. */
sk->sk_prot->hash(sk);
}
if (sk->sk_prot->init) {
err = sk->sk_prot->init(sk);
if (err)
inet_sock_release(sk);
}
out:
return err;
out_sk_free:
rcu_read_unlock();
sk_free(sk);
goto out;
}
  这里的sk_alloc是重点:
  sk = sk_alloc(PF_INET, GFP_KERNEL, inet_sk_size(protocol),
  inet_sk_slab(protocol));
  inet_sk_size定义例如以下:
  static __inline__ int inet_sk_size(int protocol)
  {
  int rc = sizeof(struct tcp_sock);
  if (protocol == IPPROTO_UDP)
  rc = sizeof(struct udp_sock);
  else if (protocol == IPPROTO_RAW)
  rc = sizeof(struct raw_sock);
  return rc;
  }
  它会依据详细的传输层协议定义返回对应的传输控制块的大小。
  在socket里,sock指针仅仅是一个“泛型”,它可能指向struct sock,struct tcp_sock,struct udp_sock,根据该协议的细节。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号