加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码门户网 (https://www.92codes.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核分析 - 网络[十六]:TCP三次握手

发布时间:2016-09-28 12:48:07 所属栏目:Linux 来源:站长网
导读:副标题#e# 内核:2.6.34 TCP是应用最广泛的传输层协议,其提供了面向连接的、可靠的字节流服务,但 也正是因为这些特性,使得TCP较之UDP异常复杂,还是分两部分[创建与使用]来进行分析。这篇主要包括TCP的创建及三次握手 的过程。 编程时一般用如下语句创建

sock_alloc_inode()中通过kmem_cache_alloc()分配了struct socket_alloc结构体大小的空间,而struct socket_alloc结构体定义如下,但只返回了inode,实际上socket和inode都已经分配了空间,在之后就可以通过container_of取 到socket。

static struct inode *sock_alloc_inode(struct super_block *sb) 

    
{     
 struct socket_alloc *ei;     
 ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);     
 …..     
 return &ei->vfs_inode;     
}     
struct socket_alloc {     
 struct socket socket;     
 struct inode vfs_inode;     
};     
         
net_families[AF_INET]:     
static const struct net_proto_family inet_family_ops = {     
 .family = PF_INET,     
 .create = inet_create,     
 .owner = THIS_MODULE,     
};

err = pf->create(net, sock, protocol, kern); ==> inet_create()

这段代 码就是从inetsw[]中取到适合的协议类型answer,sock->type就是传入socket()函数的type参数SOCK_DGRAM,最终取得结果 answer->ops==inet_stream_ops,从上面这段代码还可以看出以下问题:

socket(AF_INET, SOCK_RAW, IPPROTO_IP)这样是不合法的,因为SOCK_RAW没有默认的协议类型;同样socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) 与socket(AF_INET, SOCK_DGRAM, IPPROTO_TCP)是一样的,因为TCP的默认协议类型是IPPTOTO_TCP;SOCK_STREAM与IPPROTO_UDP 同上。

sock->state = SS_UNCONNECTED;     
list_for_each_entry_rcu(answer, &inetsw[sock->type], list) {     
 err = 0;     
 /* 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;     
 }     
 err = -EPROTONOSUPPORT;     
}

sock->ops指向inet_stream_ops,然后创建sk,sk->proto指向tcp_prot,注意这里分配的大小是struct tcp_sock,而不仅仅是struct sock大小

sock->ops = answer->ops;     
answer_prot = answer->prot;     
……     
sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot);

然后设置inet的一些参数,这里直接将sk类型转换为inet ,因为在sk_alloc()中分配的是struct tcp_sock结构大小,返回的是struct sock,利用了第一个成员的特性,三者之间的关系 如下图:

inet = inet_sk(sk);     
……     
inet->inet_id = 0;     
sock_init_data(sock, sk);

Linux内核分析 - 网络[十六]:TCP三次握手

(编辑:源码门户网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读