实现socket监听所有网络命名空间
当前Linux内核的实现,一个socket监听在一个特定的网络命名空间中,不同的命名空间可有具有相同的socket,即可监听相同的地址端口,这样很好的实现网络隔离虚拟化的功能。但是对于网路设备来说,并不需要如此完全的隔离。比如VPN设备/路由器等,一个ike进程或者quagga进程能监听在所有的命名空间,更利于实现和管理。
这样就要求应用层socket能够接收到所有命名空间的数据包,并且能够感知当前连接的命名空间。
数据包接收
内核默认创建一个网络命名空间(init_net),起初所有的socket都监听在默认的网络命名空间。要能够接收其它命名空间的数据包,需要修改sock查找函数。在一个新的连接请求进来之后,查找监听sock时(__inet_lookup_listener),内核默认仅在接收数据包所在的命名空间查找。修改为在找不到的情况下,去init_net命名空间查找,此时,监听在init_net的socket就能接收到新的连接了。
sk = __inet_lookup_listener(dev_net(dev), hashinfo, saddr, sport, daddr, hnum, dif, flags);
if (!sk) {sk = __inet_lookup_listener(&init_net, hashinfo, saddr, sport, daddr, hnum, dif, flags);
}
以上是TCP的sock查找修改,对于UDP可做相同的修改。
数据包发送
sock的查找修改之后已经可以接收到新的连接请求,但是并没有修改sock结构中的sk_net的值,其还是init_net(socket总监听在此命名空间),不能使用其查找路由。如要能正常回复此连接请求(SYN+ACK),我们的sock需要使用接收到数据包的接口所在net_namespace的路由。所以在请求路由时,使用接收命名空间查找:
static inline struct net *sock_net(const struct sock *sk)
{return read_pnet(&sk->sk_net);
}
struct dst_entry *inet_csk_route_req(struct sock *sk, struct flowi4 *fl4, const struct request_sock *req)
{rt = ip_route_output_flow(skb_real_net, fl4, sk);
}
发送连接建立之后正常的数据包涉及到的也是路由问题,如何告诉内核代码要在哪个命名空间发送?此时需要在创建子sock的时候,把真正的接收命名空间保存在子sock中。在发送时使用。例如ip_queue_xmit函数,查询路由时使用真正的child_sk_real_net去查:
int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl)
{rt = ip_route_output_ports(child_sk_real_net, fl4, sk, daddr, inet->inet_saddr,inet->inet_dport, inet->inet_sport, sk->sk_protocol, RT_CONN_FLAGS(sk), sk->sk_bound_dev_if);
}
方能找到正确的出口路由,正常发送数据包。实现应用层socket监听多个网络命名空间。
实现socket监听所有网络命名空间相关推荐
- Linux内核网络协议栈8—socket监听
几个问题 了解以下几个问题的同学可以直接忽略下文: 1.listen 库函数主要做了什么? 2. 什么是最大并发连接请求数? 3.什么是等待连接队列? socket 监听相对还是比较简单的,先看 ...
- Android 监听 Android中监听系统网络连接打开或者关闭的实现代码
本篇文章对Android中监听系统网络连接打开或者关闭的实现用实例进行了介绍.需要的朋友参考下 很简单,所以直接看代码 复制代码 代码如下: package xxx; import android.c ...
- 多线程使用SO_REUSEPORT来实现多个socket监听同一个端口
在十几年前的 FreeBSD 中就存在 SO_REUSEPORT 参数来实现多个 socket 监听同一个端口,来提升服务器的负载,在 Linux 3.9 开始也引入了这个功能,下面就看一下例子. # ...
- android 信号强度变化,Android监听WIFI网络的变化并且获得当前信号强度
MainActivity如下: package cc.testwifi; import android.os.Bundle; import android.app.Activity; /** * De ...
- 安卓网络连接全解:包括网络连接状态的监听、网络数据使用状态的监听、获取当前网络连接情况、启动wifi、获取当前连接wifi的网络情况、扫描wifi热点
全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓网络连接情况全解:包括网络连接状态的监听.网络数据使用状态的监听.获取当前网络连接情况.启动wifi.获取当前连接wifi的网络情况.扫描wifi ...
- html5中检测网络状态的方法,前端js监听浏览器网络变化
首先,为什么要让前端判断用户的网络状态呢--为了更好的用户体验. 其次,前端能否判断网络状态?有哪些方法? 1,可以做到渐进式判断,不能做到绝对准确. 2,使用的是navigator.onLine或n ...
- Android监听手机网络变化
Android监听手机网络变化 手机网络状态发生变化会发送广播,利用广播接收者,监听手机网络变化 效果图 注册广播接收者 <?xml version="1.0" encodi ...
- java起socket监听,java socket 监听示例,javasocket,java socket监
java socket 监听示例,javasocket,java socket监 java socket监听示例: socket监听需要使用SocketServer类,如下代码:package cn. ...
- linux listen监听,Linux网络协议栈 -- socket listen监听
一.sys_listen 对面向连接的协议,在调用 bind(2)后,进一步调用 listen(2),让套接字进入监听状态: int listen(int sockfd, int backlog); ...
- python tcp不用循环监听_网络编程: TCP
1. IP 地址 概念: 标识网络中设备的地址(需要联网才有没有联网, 是没有这个地址) 表现形式: ipv4 目前主要使用的, 点分十进制的格式,(192.168.3.43) 分为 4 段, 每段的 ...
最新文章
- Linux01-Linux高级特殊权限SUID详解25
- SQL Server 批量完整备份
- python多线程同步与互斥_Python之多线程:线程互斥与线程同步
- Linux 内核完成 urb: 完成回调处理者
- 十进制 转换 2-10 进制,int的扩展方法
- 计算机桌面上的声音图标没了怎么办,Win7电脑右下角声音图标不见了怎么办?...
- H3C vrrp *** ipsec 基本配置
- 直方图均衡化 原理、流程、公式推导及matlab实现
- win 10 系统怎么显示隐藏文件
- 4G智能模组SIM7600CE兼容移远EC20
- 20000本当当豆瓣畅销书电子书免费领取,免费送
- mac换硬盘重装系统记录
- Win10系统Edge可以上网其他浏览器不能上网怎么回事
- landsat7数据预处理
- Qt 数字报阅读器 图文版
- Linux下删除特殊字符的文件或文件夹
- Python之freshman07 面向对象编程jinjie
- 【转】经济学名词解释大全汇总
- mysql 慢查询优化_MySQL 性能优化之慢查询
- page31-layui点击显示和隐藏页面层
热门文章
- 史上最难php,世界上最难的简单几何体 - 我为数学狂 - 简单学习网论坛_中高考学习交流论坛_中学生学习论坛 - Powered by phpwind...
- Altium Designer之泪点和常规铺铜操作笔记
- UNI/TUBE2新配对上线,Eswap迎来新机遇
- 谷歌是如何跌下神坛的?
- SuperMemo 15.1
- python查火车票_Python查询火车票(三)
- Busting Frame Busting
- python之生成器函数
- 明日之后手机正版服务器,明日之后能不能换区 明日之后手游渠道服怎么转换成网易官方服...
- 2022考研:数学考研备考规划