linux kernel bind()时发生了什么

配置

实验一下,我有两个口lo和enp0s3, 两个地址,如下所示。

 

真实物理口测试

访问同子网的10.0.2.2

如果没有地址,返回:Cannot assign requested address,说明bind失败了。

 

lo口测试

访问loopback地址127.0.0.1

如果没有地址,返回:Cannot assign requested address,说明bind失败了。

 

上图的红框,有个例外。

用与127.0.0.1/8同子网的127.0.0.2可以发包,bind成功了。

如果把本地地址改为127.0.0.1/24,则127.0.0.2可以发包,127.0.1.2不可以。

 

内核代码分析

inet_bind() 函数  linux/net/ipv4/af_inet.c

命中local路由的源地址可以bind成功。

 实验分析

通过实验分析如上代码。

可以观察到,lo口上的地址127.0.0.1会追加一条127.0.0.0/8的local路由(猜测目的是为了将loopback网段的包拦截在本机内并上送)。

在试验,增加一个1.0.0.1/8的地址在lo上,可以看见多了一个1.0.0.0/8的local路由

 

 

综上可以解释,为什么127.0.0.2访问127.0.0.1可以bind成功。

 

透明模式

如何突破上述限制

可以使用setsockopt(IP_TRANSPARENT),

nginx的透明代理便是这样做的,代码如下:

 

详见:

[转]使用nginx的proxy_bind选项配置透明的反向代理

 
 

 

posted on   toong  阅读(16)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决

统计

点击右上角即可分享
微信分享提示