Linux协议栈(1)——协议介绍
本系列材料是关于Linux网络内核协议栈的,总体上将其分10个文章,主要目的是简明扼要的描述Linux协议栈在内核中的实现,从总体上掌握linux网络协议栈。因为操作系统中的网络子系统非常庞大,加上本系列材料有限,所以路由系统、邻接子系统、无线系统、桥接等不会涉及,后续有机会再系列介绍。
材料先会介绍网络相关相关的TCP/IP协议族知识(本章),然后从总体上观测包的接收和发送流程及代码(第二章和第三章)。(第四章和第五章)介绍网络协议栈相关的数据结构为后续的代码解读打下基础,接着是从最新git代码分支上来走读链路层、网络层、传输层(第六章、第七章和第八章),以及网络驱动(第十章)。最后会介绍Layer5应用层的开发(第十章)以及对本系列的一个总结(第十一章)。
下面我们开始:
网络协议的正式模型其实是 OSI(Open Systems Interconnection)7层模型,但事实标准是TCP/IP四层模型,linux中的协议模型也是这TCP/IP模型的。这个是历史原因我们不去关注。
其两者模型之间的对应关系如下图所示:
对于某些问题来说,7层模型过于详细,现在完全按照七层来实现的比较少。模型中每层只能与紧邻的层通信。
本系列中基本不涉及应用层(如HTTP(Hyper text transfer protocol)、FTP(file transfer protocol)、SMTP(simple mail transfer rotocol)、POP3(post office protocol 3)、IMAP4(Internet mail access protocol))的具体细节,主要是下面三层的流程、函数和实现。
各层对应的数据如下:
应用层——消息
传输层——数据段(segment)
网络层——分组、数据包(packet)
链路层——帧(frame)
物理层——P-PDU(bit)
当然这个只是称呼,如果非要把每层都叫消息也是可以的,不过这样在交流或者看材料的时候可能会引起误解了。
本章还要先准备一些相关的知识用于后面章节的预热,主要是传输层的协议格式、网络层的协议格式、数据链路层的协议格式。
1.1.1.1 传输层(TCP/UDP)
传输层主要的是TCP和UDP,具有代表性的两个传输层协议。除此之外还有SCTP(Stream Control Transmission Protocol,流控制传输协议),DCCP(数据报拥塞控制协议Datagram Congestion Control Protocol)等传输层协议,当然远没有TCP/UDP两兄弟那么火热。
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。
它的首部如下,注意TCP首部是从20字节~60字节可变的:
如果大家对网络开发比较熟悉的话,这个图应该是比较熟悉的。当然如果不熟悉的话,可以复制下来贴在一个显眼的地方可以让自己能随时看到。
而UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。
UDP的格式如下:
他们的格式有个相同点,就是前面4个自己都是记录源端口号和目标端口号的哦。不过在这一层记住并没有IP地址,这是因为在下层网络层的时候会有IP地址的。
TCP和UDP两个协议各有优缺点,我们先记住一点就好了,TCP是可靠的,UDP是不可靠的。UDP协议时发出包之后就不管了,无法确定对端是否收到了这个包,需要应用程序来判断,而TCP协议在发出包之后是会等待对面发送ACK应答回来的,超时不发送回来说明对面没收到就会触发重传机制。
1.1.1.2 网络层(IP)
IP(网际协议,Internet Protocol).
TCP/IP心脏是互联网层。主要由IP和ICMP两个协议组成。
IP分为三大作用模块:IP寻址、路由、以及IP分包与组包。
IP包格式如下:
这个报头内容也挺多,大家不用一次记住它,可以和TCP/UDP协议头一起打印出来贴起来。
1.1.1.3 链路层(以太网帧)
最后我们来看下链路层,链路层协议有以太网、SLIP、令牌网等等,我们这里以当前最常用的以太网为例。
在数据链路层中称这种数据为帧(frame)
我们来看下以太网格式,如下图:
以太网的帧尾是一个叫做FCS(Frame Check Sequence,帧检验序列)的4个字节。用于检查帧是否有所损坏。传输过程中如果出现电子噪声干扰,可能会导致乱码位的出现。
知道这些TCP/IP协议的知识足够我们继续往下走了,至于那些RFC中陈芝麻、烂谷子的事情就不提了。
后面我们开始看在Linux网络协议栈中的接收流程。