Linux: network:socket: inet_csk_bind_conflict相关的一个改进建议

2024-04-09 13:52

本文主要是介绍Linux: network:socket: inet_csk_bind_conflict相关的一个改进建议,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

内核在分配临时端口的时候,会使用一个hash bucket存放同一端口,在reuse的情况下所有socket。在下一次选择端口的时候,会做根据fastreuse的情况,来判断是否做conflict检查。这里有一个问题:https://mzhan017.blog.csdn.net/article/details/137108073。
其实可以加一个内核参数来控制,在选择下一个临时端口的时候,是否要找hash bucket已经存在的端口,如果设置不找,就跳过存在于这些hashbucket里的端口,直接走到下一个端口。可以解决缓解避免上面fastreuse被污染的情况。

static int inet_csk_bind_conflict(const struct sock *sk,const struct inet_bind_bucket *tb,bool relax, bool reuseport_ok)
{struct sock *sk2;bool reuse = sk->sk_reuse;bool reuseport = !!sk->sk_reuseport && reuseport_ok;kuid_t uid = sock_i_uid((struct sock *)sk);/** Unlike other sk lookup places we do not check* for sk_net here, since _all_ the socks listed* in tb->owners list belong to the same net - the* one this bucket belongs to.*/sk_for_each_bound(sk2, &tb->owners) {if (sk != sk2 &&  // 这两个socket 不相同(!sk->sk_bound_dev_if || //这个新建立的socket没有 bound dev if,有conflict的存在的可能!sk2->sk_bound_dev_if ||  //或者这个table里的socket也没有 bound dev if,有conflict存在的可能sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { // 或者bound dev if 相同 就有conflict的可能,需要进一步的checkif ((!reuse || !sk2->sk_reuse ||   // 当前这个socket不可reuse,或者 table里socket有不可reuse的socket,就有conflict的可能sk2->sk_state == TCP_LISTEN) &&   //(!reuseport || !sk2->sk_reuseport ||rcu_access_pointer(sk->sk_reuseport_cb) ||(sk2->sk_state != TCP_TIME_WAIT &&!uid_eq(uid, sock_i_uid(sk2))))) {if (inet_rcv_saddr_equal(sk, sk2, true))   //需要进一步check。如果不相同的ip版本, 就直接判定无conflict。break;  ///这里有break,就代表有conflict}if (!relax && reuse && sk2->sk_reuse &&sk2->sk_state != TCP_LISTEN) {if (inet_rcv_saddr_equal(sk, sk2, true))break; ///这里有break,就代表有conflict}}}return sk2 != NULL;
}bool inet_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,bool match_wildcard)
{
//#if IS_ENABLED(CONFIG_IPV6)if (sk->sk_family == AF_INET6)return ipv6_rcv_saddr_equal(&sk->sk_v6_rcv_saddr,inet6_rcv_saddr(sk2),sk->sk_rcv_saddr,sk2->sk_rcv_saddr,ipv6_only_sock(sk),ipv6_only_sock(sk2),match_wildcard,match_wildcard);
//#endifreturn ipv4_rcv_saddr_equal(sk->sk_rcv_saddr, sk2->sk_rcv_saddr,ipv6_only_sock(sk2), match_wildcard,match_wildcard);
}/* match_sk*_wildcard == true:  0.0.0.0 equals to any IPv4 addresses* match_sk*_wildcard == false: addresses must be exactly the same, i.e.*				0.0.0.0 only equals to 0.0.0.0*/
static bool ipv4_rcv_saddr_equal(__be32 sk1_rcv_saddr, __be32 sk2_rcv_saddr,bool sk2_ipv6only, bool match_sk1_wildcard,bool match_sk2_wildcard)
{if (!sk2_ipv6only) {if (sk1_rcv_saddr == sk2_rcv_saddr)return true;return (match_sk1_wildcard && !sk1_rcv_saddr) ||(match_sk2_wildcard && !sk2_rcv_saddr);}return false;
}
Samples: 86K of event 'cpu-clock:pppH', Event count (approx.): 21709000000
Overhead  Command          Shared Object        Symbol30.59%  ngss             [kernel.kallsyms]    [k] inet_csk_bind_conflict16.59%  swapper          [kernel.kallsyms]    [k] native_safe_halt1.92%  swapper          [kernel.kallsyms]    [k] __softirqentry_text_start1.74%  ngss             ngss                 [.] 0x0000000000a2a5061.10%  ngss             ngss                 [.] 0x0000000001f320c31.05%  ngss             [kernel.kallsyms]    [k] _raw_spin_unlock_irqrestoreSamples: 104K of event 'cpu-clock:pppH', Event count (approx.): 26226000000
Overhead  Command          Shared Object        Symbol31.33%  swapper          [kernel.kallsyms]    [k] native_safe_halt1.57%  swapper          [kernel.kallsyms]    [k] __softirqentry_text_start1.53%  ngss             ngss                 [.] 0x0000000000a2a506

这篇关于Linux: network:socket: inet_csk_bind_conflict相关的一个改进建议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/888324

相关文章

Linux下修改hostname的三种实现方式

《Linux下修改hostname的三种实现方式》:本文主要介绍Linux下修改hostname的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下修改ho编程stname三种方式方法1:修改配置文件方法2:hFvEWEostnamectl命

Linux虚拟机不显示IP地址的解决方法(亲测有效)

《Linux虚拟机不显示IP地址的解决方法(亲测有效)》本文主要介绍了通过VMware新装的Linux系统没有IP地址的解决方法,主要步骤包括:关闭虚拟机、打开VM虚拟网络编辑器、还原VMnet8或修... 目录前言步骤0.问题情况1.关闭虚拟机2.China编程打开VM虚拟网络编辑器3.1 方法一:点击还原VM

Linux搭建Mysql主从同步的教程

《Linux搭建Mysql主从同步的教程》:本文主要介绍Linux搭建Mysql主从同步的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux搭建mysql主从同步1.启动mysql服务2.修改Mysql主库配置文件/etc/my.cnf3.重启主库my

Linux系统之authconfig命令的使用解读

《Linux系统之authconfig命令的使用解读》authconfig是一个用于配置Linux系统身份验证和账户管理设置的命令行工具,主要用于RedHat系列的Linux发行版,它提供了一系列选项... 目录linux authconfig命令的使用基本语法常用选项示例总结Linux authconfi

jdk21下载、安装详细教程(Windows、Linux、macOS)

《jdk21下载、安装详细教程(Windows、Linux、macOS)》本文介绍了OpenJDK21的下载地址和安装步骤,包括Windows、Linux和macOS平台,下载后解压并设置环境变量,最... 目录1、官网2、下载openjdk3、安装4、验证1、官网官网地址:OpenJDK下载地址:Ar

linux本机进程间通信之UDS详解

《linux本机进程间通信之UDS详解》文章介绍了Unix域套接字(UDS)的使用方法,这是一种在同一台主机上不同进程间通信的方式,UDS支持三种套接字类型:SOCK_STREAM、SOCK_DGRA... 目录基础概念本机进程间通信socket实现AF_INET数据收发示意图AF_Unix数据收发流程图A

linux环境openssl、openssh升级流程

《linux环境openssl、openssh升级流程》该文章详细介绍了在Ubuntu22.04系统上升级OpenSSL和OpenSSH的方法,首先,升级OpenSSL的步骤包括下载最新版本、安装编译... 目录一.升级openssl1.官网下载最新版openssl2.安装编译环境3.下载后解压安装4.备份

linux打包解压命令方式

《linux打包解压命令方式》文章介绍了Linux系统中常用的打包和解压命令,包括tar和zip,使用tar命令可以创建和解压tar格式的归档文件,使用zip命令可以创建和解压zip格式的压缩文件,每... 目录Lijavascriptnux 打包和解压命令打包命令解压命令总结linux 打包和解压命令打

linux如何复制文件夹并重命名

《linux如何复制文件夹并重命名》在Linux系统中,复制文件夹并重命名可以通过使用“cp”和“mv”命令来实现,使用“cp-r”命令可以递归复制整个文件夹及其子文件夹和文件,而使用“mv”命令可以... 目录linux复制文件夹并重命名我们需要使用“cp”命令来复制文件夹我们还可以结合使用“mv”命令总

Linux使用cut进行文本提取的操作方法

《Linux使用cut进行文本提取的操作方法》Linux中的cut命令是一个命令行实用程序,用于从文件或标准输入中提取文本行的部分,本文给大家介绍了Linux使用cut进行文本提取的操作方法,文中有详... 目录简介基础语法常用选项范围选择示例用法-f:字段选择-d:分隔符-c:字符选择-b:字节选择--c