21.6 网络协议栈(Network Stack)
Last updated
Last updated
与packet的协议和格式对应的是运行在主机上的网络协议栈。人们有各种各样的方式来组织网络软件,接下来我会介绍最典型的,并且至少我认为是最标准的组织方式。
假设我们现在在运行Linux或者XV6,我们有一些应用程序比如浏览器,DNS服务器。这些应用程序使用socket API打开了socket layer的文件描述符。Socket layer是内核中的一层软件,它会维护一个表单来记录文件描述符和UDP/TCP端口号之间的关系。同时它也会为每个socket维护一个队列用来存储接收到的packet。我们在networking lab中提供的代码模板包含了一个非常原始的socket layer。
在socket layer之下是UDP和TCP协议层。UDP软件几乎不做任何事情,它只是检查收到的packet,获取目的端口号,并将UDP payload传输给socket layer中对应的队列。TCP软件会复杂的多,它会维护每个TCP连接的状态,比如记录每个TCP连接的序列号,哪些packet没有被ACK,哪些packet需要重传。所以TCP的协议控制模块会记录大量的状态,但是UDP中不会记录任何状态。UDP和TCP通常被称为传输层。networking lab提供的代码中有一个简单的UDP层,但是没有TCP的代码。
在TCP/UDP之下是IP层,IP层的软件通常很简单。虽然我不确定是在同一层还是下一层,与IP层在一起的还有ARP层。
再往下的话,我们可以认为还会有一层以太网。但是通常并没有一个独立的以太网层。通常来说这个位置是一个或者多个网卡驱动,这些驱动与实际的网卡硬件交互。网卡硬件与局域网会有实际的连接。
当一个packet从网络送达时,网卡会从网络中将packet接收住并传递给网卡驱动。网卡驱动会将packet向网络协议栈上层推送。在IP层,软件会检查并校验IP header,将其剥离,再把剩下的数据向上推送给UDP。UDP也会检查并校验UDP header,将其剥离,再把剩下的数据加入到socket layer中相应文件描述符对应的队列中。所以一个packet在被收到之后,会自底向上逐层解析并剥离header。当应用程序发送一个packet,会自顶向下逐层添加header,直到最底层packet再被传递给硬件网卡用来在网络中传输。所以内核中的网络软件通常都是被嵌套的协议所驱动。
这里实际上我忘了一件重要的事情,在整个处理流程中都会有packet buffer。所以当收到了一个packet之后,它会被拷贝到一个packet buffer中,这个packet buffer会在网络协议栈中传递。通常在不同的协议层之间会有队列,比如在socket layer就有一个等待被应用程序处理的packet队列,这里的队列是一个linked-list。通常整个网络协议栈都会使用buffer分配器,buffer结构。在我们提供的networking lab代码中,buffer接口名叫MBUF。
以上就是一个典型的网络协议栈的分层图。