Linux内核中一切皆为文件,网络协议栈在内核中以文件系统sockfs存在,该文件系统中的文件就是套接字,Linux抽象所有文件系统,通过VFS虚拟文件系统统一管理,网络系统也是这样,当中也存在超级块、索引节点、目录项。
在proc文件系统通过如下方式得到当前内核所有文件系统总称:
观察到文件系统分为第一列有nodev和无nodev,前者只存在于内核中,采用非持久性的存储方式,后者则存在于磁盘这样的块设备中。这里注意,sockfs的“虚拟“和VFS的“虚拟”是两个不同概念。前者表示sockfs不存在于磁盘中,它们存在于内存中,只要系统重启信息全部丢失。而虚拟文件系统是对所有文件系统的一种抽象,将所有不同文件系统的共同信息放入同一组数据结构中,为上层提供统一接口。
VFS用于描述文件系统类型的数据结构为file_system_type。
static struct file_system_type sock_fs_type = {
.name = "sockfs",
.get_sb = sockfs_get_sb,
.kill_sb = kill_anon_super,
};
static struct file_system_type proc_fs_type = {
.name = "proc",
.get_sb = proc_get_sb,
.kill_sb = proc_kill_sb,
};
文件系统名称从file_system_type中的name获得。
socket结构:
内核中通过socket结构表示套接字,包含描述套接字状态的state,套接字标志位flag,等待队列wait,与套接字相关的文件对象file。
/**
* struct socket - general BSD socket
* @state: socket state (%SS_CONNECTED, etc)
* @type: socket type (%SOCK_STREAM, etc)
* @flags: socket flags (%SOCK_ASYNC_NOSPACE, etc)
* @ops: protocol specific socket operations
* @fasync_list: Asynchronous wake up list
* @file: File back pointer for gc
* @sk: internal networking protocol agnostic socket representation
* @wait: wait queue for several uses
*/
struct socket {
socket_state state;
short type;
unsigned long flags;
const struct proto_ops *ops;
struct fasync_struct *fasync_list;
struct file *file;
struct sock *sk;
wait_queue_head_t wait;
};
在该结构中包含一个类似的结构struct sock,也描述套接字,struct sock含有大量字段描述协议通用属性,而socket描述应用程序相关部分。
struct sk_buf 用于描述网络协议中的数据包,无论数据包处于哪一层都会有一个sk_buf与之对应,通过结构内部的几个指针结构可以完成去包头和加包头操作。
三者关系:
每个socket结构都有一个sk字段指向sock结构,sock结构存在sk_sock结构反指向socket结构,struct sock通过struct sk_buff_head sk_receive_queue和sk_write_queue,指向struct sk_buff_head头部,sk_buff_head中有struct sk_buff *next和*prev指向真正的sk_buf。