理解 Linux网络栈(1):Linux 网络协议栈简单总结( 四 )
文章插图
1.2.3 传输层 (TCP/UDP)
- 传输层 TCP 处理入口在 tcp_v4_rcv 函数(位于 linux/net/ipv4/tcp ipv4.c 文件中) , 它会做 TCP header 检查等处理 。
- 调用 _tcp_v4_lookup , 查找该 package 的 open socket 。 如果找不到 , 该 package 会被丢弃 。 接下来检查 socket 和 connection 的状态 。
- 如果socket 和 connection 一切正常 , 调用 tcp_prequeue 使 package 从内核进入 user space , 放进 socket 的 receive queue 。 然后 socket 会被唤醒 , 调用 system call , 并最终调用 tcp_recvmsg 函数去从 socket recieve queue 中获取 segment 。
- 每当用户应用调用 read 或者 recvfrom 时 , 该调用会被映射为/net/socket.c 中的 sys_recv 系统调用 , 并被转化为 sys_recvfrom 调用 , 然后调用 sock_recgmsg 函数 。
- 对于 INET 类型的 socket , /net/ipv4/af inet.c 中的 inet_recvmsg 方法会被调用 , 它会调用相关协议的数据接收方法 。
- 对 TCP 来说 , 调用 tcp_recvmsg 。 该函数从 socket buffer 中拷贝数据到 user buffer 。
- 对 UDP 来说 , 从 user space 中可以调用三个 system call recv()/recvfrom()/recvmsg() 中的任意一个来接收 UDP package , 这些系统调用最终都会调用内核中的 udp_recvmsg 方法 。
文章插图
2. Linux sk_buff struct 数据结构和队列(Queue)2.1 sk_buff(本章节摘选自 )
2.1.1 sk_buff 是什么
当网络包被内核处理时 , 底层协议的数据被传送更高层 , 当数据传送时过程反过来 。 由不同协议产生的数据(包括头和负载)不断往下层传递直到它们最终被发送 。 因为这些操作的速度对于网络层的表现至关重要 , 内核使用一个特定的结构叫 sk_buff ,其定义文件在 skbuffer.h 。 Socket buffer被用来在网络实现层交换数据而不用拷贝来或去数据包 –这显著获得速度收益 。
- sk_buff 是 Linux 网络的一个核心数据结构 , 其定义文件在 skbuffer.h 。
- socket kernel buffer (skb) 是 Linux 内核网络栈(L2 到 L4)处理网络包(packets)所使用的 buffer , 它的类型是 sk_buffer 。 简单来说 , 一个 skb 表示 Linux 网络栈中的一个 packet;TCP 分段和 IP 分组生产的多个 skb 被一个 skb list 形式来保存 。
- struct sock 有三个 skb 队列(sk_buffer queue) , 分别是 rx , tx 和 err 。
文章插图
它的主要结构成员:
struct sk_buff {/* These two members must be first. */ # packet 可以存在于 list 或者 queue 中 , 这两个成员用于链表处理struct sk_buff*next;struct sk_buff*prev;struct sk_buff_head*list; #该 packet 所在的 list ...struct sock*sk;#跟该 skb 相关联的 socketstruct timevalstamp; # packet 发送或者接收的时间 , 主要用于 packet sniffersstruct net_device*dev;#这三个成员跟踪该 packet 相关的 devices , 比如接收它的设备等struct net_device*input_dev;struct net_device*real_dev;union {#指向各协议层 header 结构struct tcphdr*th;struct udphdr*uh;struct icmphdr*icmph;struct igmphdr*igmph;struct iphdr*ipiph;struct ipv6hdr*ipv6h;unsigned char*raw;} h;union {struct iphdr*iph;struct ipv6hdr*ipv6h;struct arphdr*arph;unsigned char*raw;} nh;union {unsigned char*raw;} mac;structdst_entry*dst; #指向该 packet 的路由目的结构 , 告诉我们它会被如何路由到目的地charcb[40];# SKB control block , 用于各协议层保存私有信息 , 比如 TCP 的顺序号和帧的重发状态unsigned intlen, #packet 的长度data_len,mac_len,# MAC header 长度csum;# packet 的 checksum , 用于计算保存在 protocol header 中的校验和 。 发送时 , 当 checksum offloading 时 , 不设置;接收时 , 可以由device计算unsigned charlocal_df, #用于 IPV4 在已经做了分片的情况下的再分片 , 比如 IPSEC 情况下 。cloned:1, #在 skb 被 cloned 时设置 , 此时 , skb 各成员是自己的 , 但是数据是shared的nohdr:1,#用于支持 TSOpkt_type, #packet 类型ip_summed; # 网卡能支持的校验和计算的类型 , NONE 表示不支持 , HW 表示支持 ,__u32priority; #用于 QoSunsigned shortprotocol, # 接收 packet 的协议security;12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
- 设计模式6之代理模式
- 退休主任医师的网络医生经验:一天最多能看20人 很要耐心
- Nginx服务器屏蔽与禁止屏蔽网络爬虫的方法
- 监控摄像头被黑!Mirai僵尸网络再作乱物联网设备成重灾区
- 在图上发送消息的神经网络MPNN简介和代码实现
- Linux培训完能到什么水平,之后还需要学习哪些技术?
- 如何使用 lshw 查看 Linux 设备信息
- 网络安全:如何使用MSFPC半自动化生成强大的木码?「下集」
- 人工智能驱动的零接触网络在5G世界中的作用
- AMD Radeon图形驱动占到了Linux内核的10.5%