网站首页 > 技术文章 正文
1. 前言
Web 前端思考题:如何获取往返数据包的 TTL
注意,这里说的是「往返」,即去程和返程,也就是「服务端」收到「客户端数据包」的 TTL,和「客户端」收到「服务端数据包」的 TTL。
注意,这里说的是「接收」,毕竟发送时的 TTL 毫无意义,服务端固定已知,客户端通常是 64 或 128(和操作系统相关)。
这个问题的初衷,是想通过 JS 检测用户和服务器之间的往返路由数。虽然大多情况下往返链路相近,但也存在差异较大的情况。例如访问某些香港服务器,去程电信直连,而返程则会到日本绕一圈,链路差异非常大。
2. 去程
去程 TTL 很容易获取,直接读取 Web 服务器的 socket 即可(例如通过 getsockopt)。或者用 raw socket/libpcap 抓包也不难实现。
3. 返程
返程 TTL 就没那么容易获取了。
也许你会说,可通过服务器 traceroute 反查。这种方案虽然可行,但并不准确。如今用户几乎都在内网中,反查只能到用户的公网路由器,内网的路由数仍无法获取。而且反查效率很低,需要发不少数据包。
但用 JS 读取数据包 TTL 更不可行,毕竟浏览器功能十分有限。抓包这种操作,想都不用想;而 getsockopt 这类高权限 API,浏览器显然不可能提供。因此我们得另辟蹊径。
4. 思路
设想下,假如客户端能把某个「收到的数据包」封装在「另一种数据包」的内容里回传给服务器,那我们就可以在服务器上获取返程信息了。
事实上,这种情况是存在的!「ICMP 端口不可到达」协议专做这事。
那么,客户端在什么情况下会触发这种 ICMP?只要浏览器在收到服务器数据包之前断开连接即可。之后数据包达到时,由于操作系统找不到目标端口对应的连接,只能丢弃该包,同时回复一个「ICMP 端口不可到达」告知服务器。
该 ICMP 的内容部分,正是被丢弃包的网络层和传输层头,包含了我们想要的返程信息。
因此我们的核心思路:
- JS 向服务器发包
- 服务器稍作延迟,回复任意内容
- JS 在收到包之前释放连接
- 服务器抓取 ICMP (type=3, code=3) 类型的包
由于 TCP 连接是操作系统维护的,JS 难以精确控制释放时间,因此我们使用更简单的 UDP。通过 WebRTC 即可实现 UDP 连接的创建和关闭。
并且 TCP 是有状态的,连接断开后 NAT 会删除条目,服务器返回的数据包可能进不了内网。而 UDP 是无状态的,本地关闭连接对 NAT 毫无感知,此后一段时间里数据仍可进入内网。
5. 实现
实现比思考简单得多,这里就不讲解了。
需要注意的是,JS 向服务器发送 UDP 包时需携带一个 uuid 数据,用于之后获取数据时的关联。
6. 局限
不过并非所有情况下都能成功获取,例如有些操作系统禁用了端口不可到达的响应,有些运营商会丢弃这类 ICMP 包。
如果演示页面显示 fail,那就是无法获取了。(如果是 network err 可能测试服务关了~)
当然,本文纯属开脑洞而已,顺便分享一点点网络小知识~
猜你喜欢
- 2025-06-10 下一代 Vue3 Devtools 正式开源!(vue3正式版发布)
- 2025-06-10 HyperExpress 来了,老牌 Express 要下线?
- 2025-06-10 大厂面试必问:如何设计一个扛高并发的系统?
- 2025-06-10 初学vue3, 全是黑盒子,vue3知识点汇总
- 2025-06-10 62K Star!Syncthing,打造你的专属局域网文件同步利器!
- 2024-09-30 Vue Router 4 路由地址详解 vue router路由配置
- 2024-09-30 「vue基础」一篇浅显易懂的 Vue 路由使用指南( Vue Router 下)
- 2024-09-30 Vue Router 4 路由操作 - 路由导航
- 2024-09-30 为什么用vue.js,为什么前端开发46%的人都在用?
- 2024-09-30 vue-router 基础:4类路由跳转示例
你 发表评论:
欢迎- 502℃几个Oracle空值处理函数 oracle处理null值的函数
- 500℃Oracle分析函数之Lag和Lead()使用
- 496℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 491℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 483℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 474℃【数据统计分析】详解Oracle分组函数之CUBE
- 457℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 455℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端富文本编辑器 (47)
- 前端路由 (61)
- 前端数组 (73)
- 前端定时器 (47)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)