1.2024年度Linux6.9内核最新源码解读-网络篇-【server端】-【第一步】创建--socket
2.正点原子lwIP学习笔记——IP协议
3.Linux内核源码解析---EPOLL实现4之唤醒等待进程与惊群问题
4.linux内核源码:网络通信简介——网络拥塞控制之BBR算法
5.linux Netfilter在网络层的实现详细分析(iptables)
6.免费 IP 地址查询 API 请求示例以及私有化部署方案源码可用
2024年度Linux6.9内核最新源码解读-网络篇-【server端】-【第一步】创建--socket
深入解析年Linux 6.9内核的网络篇,从服务端的第一步:创建socket开始。理解用户空间与内核空间的交互至关重要。当我们在用户程序中调用socket(AF_INET, SOCK_STREAM, 0),实际上是触发了从用户空间到内核空间的系统调用sys_socket(),这是流控授权源码创建网络连接的关键步骤。 首先,让我们关注sys_socket函数。这个函数在net/socket.c文件的位置,无论内核版本如何,都会调用__sys_socket_create函数来实际创建套接字,它接受地址族、类型、协议和结果指针。创建失败时,会返回错误指针。 在socket创建过程中,参数解析至关重要:网络命名空间(net):隔离网络环境,每个空间有自己的配置,如IP地址和路由。
协议族(family):如IPv4(AF_INET)或IPv6(AF_INET6)。
套接字类型(type):如流式(SOCK_STREAM)或数据报(SOCK_DGRAM)。
协议(protocol):如TCP(IPPROTO_TCP)或UDP(IPPROTO_UDP),默认值自动选择。
结果指针(res):指向新创建的socket结构体。
内核标志(kern):区分用户空间和内核空间的socket。
__sock_create函数处理创建逻辑,调用sock_map_fd映射文件描述符,支持O_CLOEXEC和O_NONBLOCK选项。每个网络协议族有其特有的create函数,如inet_create处理IPv4 TCP创建。 在内核中,安全模块如LSM会通过security_socket_create进行安全检查。sock_alloc负责内存分配和socket结构初始化,协议族注册和动态加载在必要时进行。RCU机制保护数据一致性,飞蛾2.0源码确保在多线程环境中操作的正确性。 理解socket_wq结构体对于异步IO至关重要,它协助socket管理等待队列和通知。例如,在TCP协议族的inet_create函数中,会根据用户请求找到匹配的协议,并设置相关的操作集和数据结构。 通过源码,我们可以看到socket和sock结构体的关系,前者是用户空间操作的抽象,后者是内核处理网络连接的实体。理解这些细节有助于我们更好地编写C++网络程序。 此外,原始套接字(如TCP、UDP和CMP)的应用示例,以及对不同协议的深入理解,如常用的IP协议、专用协议和实验性协议,是进一步学习和实践的重要部分。正点原子lwIP学习笔记——IP协议
IP协议,作为TCP/IP协议族的核心,负责TCP、UDP、ICMP、IGMP等数据的传输(IPv4和IPv6)。它提供了无连接、不可靠的服务,这意味着数据传输不需维持对方信息,每次发送数据都需要明确目标IP地址,且不能保证数据包准确到达,只尽力而为,如发送失败会通知上层协议但不重传。
IP协议的功能包括:寻址,当主机间跨网段通信时,数据通过主机发送到路由器,发卡后台源码路由器根据IP地址的网络号和主机号进行转发;利用路由表决定数据包的传输路径,目标网络、下一跳地址和子网掩码是关键信息;当数据包大小超过MTU(通常字节),则需要进行分片和重组。
IP协议与ARP、ICMP和IGMP等配合工作。与MAC地址(物理地址)不同,IP地址是网络层以上的标识,分为五类。理解IP协议内容,IPv4的首部结构包含字节的固定部分,如差分服务区域、总长度、标识符、标志等,以及源和目标IP地址等信息。
IP分片原理涉及MTU限制,当数据包超过MTU,就需要进行分片操作,比如字节的数据可能被分为多个片段,每个片段包含偏移量、标志等字段。pbuf内存分配和重组过程是关键,例如,使用pbuf结构存储和传递数据,TCP和IP头部会插入pbuf,通过ip_reassdata结构连接分片,直到所有分片接收完整后进行重组。
IP重组是根据到达顺序重新组合分片,lwIP处理分片时,ip_reassdata链表用于存储和管理未完整接收的数据包。源码中的函数如ip4_reass()和ip_reass_chain_frag_into_datagram_and_validate()处理了这些逻辑,确保数据包在到达目的地后正确组合。
总的来说,理解lwIP协议的趋势出源码这部分内容,关注核心原理和源码示例,把握数据传输的完整逻辑,包括IP首部字段、分片与重组,以及与MAC地址、TCP/IP协议的交互,是十分重要的。
Linux内核源码解析---EPOLL实现4之唤醒等待进程与惊群问题
在Linux内核源码的EPOLL实现中,第四部分着重探讨了数据到来时如何唤醒等待进程以及惊群问题。当网卡接收到数据,DMA技术将数据复制到内存RingBuffer,通过硬中断通知CPU,然后由ksoftirqd线程处理,最终数据会进入socket接收队列。虽然ksoftirqd的创建过程不在本节讨论,但核心是理解数据如何从协议层传递到socket buffer。
在tcp_ipv4.c中,当接收到socket buffer时,会首先在连接表和监听表中寻找对应的socket。一旦找到,进入tcp_rcv_established函数,这里会检查socket是否准备好接收数据,通过调用sock_data_ready,其初始值为sock_def_readable,进而进入wake_up函数,唤醒之前挂上的wait_queue_t节点。
在wake_up方法中,会遍历链表并回调ep_poll_callback,这个函数是epoll的核心逻辑。然而,如果epoll的设置没有启用WQ_FLAG_EXCLUSIVE,就会导致惊群效应,即唤醒所有阻塞在当前epoll的进程。这在default_wake_function函数中体现,如果没有特殊标记,box源码分析进程会立即被唤醒并进入调度。
总结来说,epoll的唤醒过程涉及socket buffer、协议层处理、链表操作以及回调函数,其中惊群问题与默认的唤醒策略密切相关。理解这些细节,有助于深入理解Linux内核中EPOLL的异步操作机制。
linux内核源码:网络通信简介——网络拥塞控制之BBR算法
从网络诞生至十年前,TCP拥塞控制采用的经典算法如reno、new-reno、bic、cubic等,在低带宽有线网络中运行了几十年。然而,随着网络带宽的增加以及无线网络通信的普及,这些传统算法开始难以适应新的环境。
根本原因是,传统拥塞控制算法将丢包/错包等同于网络拥塞。这一认知上的缺陷导致了算法在面对新环境时的不适应性。BBR算法的出现,旨在解决这一问题。BBR通过以下方式控制拥塞:
1. 确保源端发送数据的速率不超过瓶颈链路的带宽,避免长时间排队造成拥塞。
2. 设定BDP(往返延迟带宽积)的上限,即源端发送的待确认在途数据包(inflight)不超过BDP,换句话说,双向链路中数据包总和不超过RTT(往返延迟)与BtlBW(瓶颈带宽)的乘积。
BBR算法需要两个关键变量:RTT(RTprop:往返传播延迟时间)和BtlBW(瓶颈带宽),并需要精确测量这两个变量的值。
1. RTT的定义为源端从发送数据到收到ACK的耗时,即数据包一来一回的时间总和。在应用受限阶段测量是最合适的。
2. BtlBW的测量则在带宽受限阶段进行,通过多次测量交付速率,将近期的最大交付速率作为BtlBW。测量的时间窗口通常在6-个RTT之间,确保测量结果的准确性。
在上述概念基础上,BBR算法实现了从初始启动、排水、探测带宽到探测RTT的四个阶段,以实现更高效、更稳定的网络通信。
通信双方在节点中,通过发送和接收数据进行交互。BBR算法通过接收ACK包时更新RTT、部分包更新BtlBW,以及发送数据包时判断inflight数据量是否超过BDP,通过一系列动作实现数据的有效传输。
在具体的实现上,BBR算法的源码位于net\ipv4\tcp_bbr.c文件中(以Linux 4.9源码为例)。关键函数包括估算带宽的bbr_update_bw、设置pacing_rate来控制发送速度的bbr_set_pacing_rate以及更新最小的RTT的bbr_update_min_rtt等。
总的来说,BBR算法不再依赖丢包判断,也不采用传统的AIMD线性增乘性减策略维护拥塞窗口。而是通过采样估计网络链路拓扑情况,极大带宽和极小延时,以及使用发送窗口来优化数据传输效率。同时,引入Pacing Rate限制数据发送速率,与cwnd配合使用,有效降低数据冲击。
linux Netfilter在网络层的实现详细分析(iptables)
Linux netfilter在网络层的实现细节分析主要基于Linux内核版本4..0-。
我绘制了一张Linux内核协议栈网络层netfilter(iptables)的全景图,其中包含了许多内容,以下将详细讲解。
INGRESS入口钩子是在Linux内核4.2中引入的。与其他netfilter钩子不同,入口钩子附加到特定的网络接口。可以使用带有ingress钩子的nftables来实施非常早期的过滤策略,甚至在prerouting之前生效。请注意,在这个非常早期的阶段,碎片化的数据报尚未重新组装,例如匹配ip saddr和daddr适用于所有ip数据包,但匹配传输层的头部(如udp dport)仅适用于未分段的数据包或第一个片段,因此入口钩子提供了一种替代tc入口过滤的方法,但仍需tc进行流量整形。
Netfilter/iptables由table、chain和规则组成。
iptables的链(chain)
netfilter在网络层安装了5个钩子,对应5个链,还可以通过编写内核模块来扩展这些链的功能。
⑴五个链(chain)及对应钩子
以下是网络层五条链的位置图:
①网络数据包的三种流转路径
②源码中网络层的5个hook的定义
include\uapi\linux etfilter_ipv4.h
在include\uapi\linux etfilter.h中有对应的hook点定义:
注:在4.2及以上版本内核中又增加了一个hook点NF_NETDEV_INGRESS:
为NFPROTO_INET系列添加了NF_INET_INGRESS伪钩子。这是将这个新钩子映射到现有的NFPROTO_NETDEV和NF_NETDEV_INGRESS钩子。该钩子不保证数据包仅是inet,用户必须明确过滤掉非ip流量。这种基础结构使得在nf_tables中支持这个新钩子变得更容易。
iptables的表
⑴五张表(table)
以下是五张表分布在对应链上的图:
相关视频推荐
免费学习地址:Linux C/C++开发(后端/音视频/游戏/嵌入式/高性能网络/存储/基础架构/安全)
需要C/C++ Linux服务器架构师学习资料加qun 获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享
⑵源码中IP层的表的定义
netfilter中的表的定义
include\linux etfilter\x_tables.h
网络层各hook点的优先级
数值越低优先级越高:
include\uapi\linux etfilter_ipv4.h
下面我们看下netfilter/iptables的这几张表在内核源码中的定义。
①raw表
源码里RAW_VALID_HOOKS宏可以看出raw表只有NF_INET_PRE_ROUTING、NF_INET_LOCAL_OUT链有效。
②mangle表
源码中valid_hooks参数可以看出mangle表对NF_INET_PRE_ROUTING、NF_INET_LOCAL_IN、NF_INET_FORWARD、NF_INET_LOCAL_OUT、NF_INET_POST_ROUTING五条链都有效。
③nat表
valid_hooks变量可以看出nat表只有NF_INET_PRE_ROUTING、NF_INET_POST_ROUTING、NF_INET_LOCAL_OUT、NF_INET_LOCAL_IN四条链有效。
④filter表
源码中valid_hooks参数可以看出filter表对NF_INET_LOCAL_IN、NF_INET_FORWARD、NF_INET_LOCAL_OUT三条链有效。
网络层的五张表在内核中对应了五个内核模块:
3、Netfilter在网络层安装的5个hook点
下面我们看下网络层的各个hook点安装的位置:
⑴、NF_INET_PRE_ROUTING
它是所有传入数据包到达的第一个hook点,它是在路由子系统中执行查找之前。这个钩子在IPv4的ip_rcv()方法中,在IPv6的ipv6_rcv()方法中。
①net\ipv4\ip_input.c
②net\ipv4\xfrm4_input.c
⑵、NF_INET_LOCAL_IN
这个钩子在IPv4的ip_local_deliver()方法中,在IPv6的ip6_input()方法中。所有路由到本地主机的数据包都会到达此hook点,它是在首先通过NF_INET_PRE_ROUTING hook点并在路由子系统中执行查找之后进到这里。
net\ipv4\ip_input.c
⑶、NF_INET_FORWARD
①net\ipv4\ip_forward.c
②net\ipv4\ipmr.c
⑷、NF_INET_LOCAL_OUT
①net\ipv4\ip_output.c
②net\ipv4\raw.c
⑸、NF_INET_POST_ROUTING
net\ipv4\ip_output.c
以上我们看到xfrm中也有安装相关hook点,这里引用官方资料介绍下什么是xfrm:
xfrm是IP层的一个框架,用于封装实现IPSec协议。
简单来说,xfrm就是IP层的一个框架,用于封装实现IPSec协议。
到此,我们基于源码分析介绍完了Netfilter在网络层的实现。
免费 IP 地址查询 API 请求示例以及私有化部署方案源码可用
查询 IPv4 地址的区域与城市详情,简化开发流程。
接口请求流程举例:请求返回结果:
部署私有 IP 地址查询 API 至本地或专有云服务器,适用于 WEB API 服务环境。
提供集成数据安全性与高性能的服务。一键启动私有化部署方案,保障数据安全。
享受一键部署的便捷性,同时支持高并发与低延迟的需求。
部署自定义 IP 地址查询 API,确保数据在其私有网络内流通,加强隐私保护。
源代码可用,助力开发者快速集成与自定义功能。
解析LinuxSS源码探索一探究竟linuxss源码
被誉为“全球最复杂开源项目”的Linux SS(Secure Socket)是一款轻量级的网络代理工具,它在Linux系统上非常受欢迎,也成为了大多数网络应用的首选。Linux SS的源码的代码量相当庞大,也备受广大开发者的关注,潜心钻研Linux SS源码对于网络研究者和黑客们来说是非常有必要的。
我们以Linux 3. 内核的SS源码为例来分析,Linux SS的源码目录位于linux/net/ipv4/netfilter/目录下,在该目录下包含了Linux SS的主要代码,我们可以先查看其中的主要头文件,比如说:
include/linux/netfilter/ipset/ip_set.h
include/linux/netfilter_ipv4/ip_tables.h
include/linux/netfilter/x_tables.h
这三个头文件是Linux SS系统的核心结构之一。
接下来,我们还要解析两个核心函数:iptables_init函数和iptables_register_table函数,这两个函数的主要作用是初始化网络过滤框架和注册网络过滤表。iptables_init函数主要用于初始化网络过滤框架,主要完成如下功能:
1. 调用xtables_init函数,初始化Xtables模型;
2. 调用ip_tables_init函数,初始化IPTables模型;
3. 调用nftables_init函数,初始化Nftables模型;
4. 调用ipset_init函数,初始化IPset模型。
而iptables_register_table函数主要用于注册网络过滤表,主要完成如下功能:
1. 根据提供的参数检查表的有效性;
2. 创建一个新的数据结构xt_table;
3. 将该表注册到ipt_tables数据结构中;
4. 将表名及对应的表结构存放到xt_tableshash数据结构中;
5. 更新表的索引号。
到这里,我们就大致可以了解Linux SS的源码,但Learning Linux SS源码只是静态分析,细节的分析还需要真正的运行环境,观察每个函数的实际执行,而真正运行起来的Linux SS,是与系统内核非常紧密结合的,比如:
1. 调用内核函数IPv6_build_route_tables_sockopt,构建SS的路由表;
2. 调用内核内存管理系统,比如kmalloc、vmalloc等,分配SS所需的内存;
3. 初始化Linux SS的配置参数;
4. 调用内核模块管理机制,加载Linux SS相关的内核模块;
5. 调用内核功能接口,比如netfilter, nf_conntrack, nf_hook等,通过它们来执行对应的网络功能。
通过上述深入了解Linux SS源码,我们可以迅速把握Linux SS的构架和实现,也能熟悉Linux SS的具体运行流程。Linux SS的深层原理揭示出它未来的发展趋势,我们也可以根据Linux SS的现有架构改善Linux的网络安全机制,进一步开发出与Linux SS和系统内核更加融合的高级网络功能。