Mosquitto 0.4.1 发布解读修复新订阅场景下保留消息查找的主题匹配正则缺陷【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址: https://gitcode.com/gh_mirrors/mos/mosquittoEclipse Mosquitto 0.4.1 是 2010-01-12 发布的一个纯缺陷修复bugfix版本其唯一改动是修复了客户端建立新订阅时用于查找应下发的保留消息retained message的正则表达式。版本发布公告 原文只有一句话但这一行改动背后牵涉 MQTT 代理最核心的机制之一——保留消息在新订阅时的即时投递以及早期 Mosquitto 用正则做主题匹配的历史实现。本文结合仓库中保留至今的旧正则文档、当时的 ChangeLog 记录与现代源码实现完整还原这次修复的技术背景、问题根源与演进脉络。一、发布背景一次聚焦的 bugfixChangeLog.txt 中对 0.4.1 的记录与发布公告完全一致0.4.1 - 20100112Fix regex used for finding retained messages to send on new subscription.结合 ChangeLog 上下文可以还原当时的版本节奏0.4 于 20100105 发布引入了与#通配符订阅支持、全非阻塞网络 I/O、$SYS消息统计等一批大改动一周后推出的 0.4.1 只包含上述这一项正则修复。也就是说这次修复直接服务于 0.4 新增的通配符订阅能力——0.4 之前代理不支持/#而新订阅时匹配并下发保留消息的逻辑必须与新的通配符语义对齐这正是 0.4.1 修补的薄弱点。二、修复对象新订阅时的保留消息投递MQTT 协议规定当客户端订阅某个主题过滤器时代理如果保存着匹配该过滤器的保留消息应立即把该消息以及主题作为正常发布消息推送给订阅者。0.4.1 修复的正则正是用于这一场景——在客户端建立新订阅时从保留消息库中找出所有应下发的消息。这一机制在现代版本中依然存在对应 src/retain.c 中的retain__queue()入口订阅建立后代理将订阅过滤器sub-topic_filter分词然后在保留消息树中查找匹配的分支把命中的保留消息逐条排入该客户端的外发队列db__message_insert_outgoing。其调用链为retain__queue()入口将过滤器用sub__topic_tokenise拆分为层级令牌retain__search()递归遍历保留消息分层结构对#、与精确层级分别处理retain__process()对每条命中的保留消息执行 ACL 检查、QoS 协商后投递。在现代实现中这个查找过程完全不依赖正则表达式而是基于按/分层 哈希子节点的数据结构遍历。而在 0.4.x 早期版本中同样的逻辑由一段按订阅过滤器动态生成的正则来完成——这正是 0.4.1 修复的对象。三、旧正则的完整结构与问题分析仓库 doc/historical/old-regex.txt 完整保留了这个被替换的旧正则及其逐行注释作者特意注明仅作存档复现。这是还原 0.4.1 修复内容的最直接证据。对于发布主题a/b/c旧实现生成的正则为^(?:(?:(a|\)(?!$))(?:(?:/(?:(b|\)(?!$)))(?:(?:/(?:c|\))|/#)?|/#)?|#)$从 doc/historical/old-regex.txt 的注释可以看出它的构造思路用^...$锚定整个主题串要求从字符串开头匹配到结尾每一级层级对应一个分支(a|\)(?!$)表示匹配字面层级a或单层通配但不能在行尾末尾层级允许c或也允许以/#结尾任何一级都可以提前用/#或直接#表示匹配剩余所有层级。结合正则结构可以推断这套旧方案存在几类明显弱点层级数硬编码。正则按Level 1 / Level 2 / Level 3逐层手工展开发布主题每多一层就需要在匹配逻辑里追加一层分支。主题层级较多时生成的正则要么不匹配、要么需要动态拼接出指数级组合难以维护且易出错。边界与嵌套组合易出漏洞。(?!$)负向前瞻用于禁止通配符停在行尾但/#、后紧跟/、foo/#与foo之间的边界语义必须逐条手工保证通配符层级增多后中间层是否也必须消耗一个实际层级#与相遇时谁优先等组合情况极易出现漏匹配或误匹配。0.4 刚引入通配符订阅这类边界在新订阅下发保留消息路径上正是最容易踩坑的地方。性能开销。每条发布主题 / 订阅过滤器都要先拼接再编译正则对代理的热路径消息路由是额外负担。0.4.1 的修复即针对此——修正后的正则或对匹配逻辑的调整保证了带通配符的订阅过滤器在检索保留消息时行为正确但具体补丁源码已不在当前仓库中其后续演进方向则在doc/historical/old-regex.txt的存档性质与后续版本源码中得到印证正则方案最终被彻底放弃。四、演进结果从正则到确定性字符匹配虽然 0.4.1 只修复了正则本身的缺陷但这段历史促成了 Mosquitto 后来对主题匹配机制的彻底重构。当前仓库中可以看到两条平行的现代实现均不再使用正则1. 发布路由侧——主题树遍历src/retain.c 的retain__search()用递归 哈希表子节点的方式实现#//精确三层语义。例如对#过滤器遍历当前节点的全部子分支并继续递归对则遍历子分支但只深入一层对精确层则HASH_FIND直接定位。retain__clean_empty_hierarchy()还会在保留消息被清除时反向回收空分支避免树结构膨胀。2. 匹配判定侧——字符级状态机libcommon/topic_common.c 中topic_matches_sub()及其公开接口mosquitto_topic_matches_sub2()libcommon/topic_common.c用逐字符扫描完成主题与过滤器的匹配遇到跳过直到下一个/遇到#则要求其必须是过滤器最后一个字符并匹配剩余全部内容同时显式校验foo、foo#、#foo、foo/#/bar等非法过滤器位置。同一文件中的mosquitto_sub_topic_check()在订阅建立阶段即拒绝这类非法过滤器libcommon/topic_common.c。这种确定性算法相比旧正则方案匹配语义完全由代码分支显式定义不再有正则边界歧义发布主题每一层只被扫描一次无正则编译与回溯开销非法过滤器在入口被拦截而非等到匹配时才暴露问题。五、正确性的持续保障测试与模糊测试正则缺陷的历史教训促使项目为主题匹配建立了严密的验证体系这也为读者提供了可自行复现的验证路径行为测试test/broker/03-pattern-matching.py 覆盖了含通配符的主题匹配在真实代理上的订阅与发布行为单元/模糊测试fuzzing 目录下的 libcommon_fuzz_topic_matching.cpp 将主题与过滤器组合作为模糊测试输入持续探测匹配逻辑的边界此外还有libcommon_fuzz_sub_topic_check2.cpp、libcommon_fuzz_pub_topic_check2.cpp分别对订阅过滤器校验与发布主题校验做模糊测试历史存档doc/historical/old-regex.txt 保留旧正则全文作为对比新旧实现差异的一手资料。六、结语Mosquitto 0.4.1 在项目历史上是一次体量极小但意义清晰的发布它修掉了 0.4 引入通配符订阅后、新订阅检索保留消息路径上的正则匹配缺陷。以今天的眼光看这次修复更像一个分水岭——正则方案在处理层级化、带通配符的 MQTT 主题时暴露出的边界与性能问题促使项目后续以分层数据结构 确定性字符匹配彻底取代了正则匹配并配套建立起测试与模糊测试防线。对想深入理解 MQTT 代理路由实现的读者而言沿着 doc/historical/old-regex.txt旧方案→ src/retain.c保留消息树→ libcommon/topic_common.c匹配算法这条线索阅读恰好可以完整走一遍这段演进史。【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址: https://gitcode.com/gh_mirrors/mos/mosquitto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
UPS维护规程实战指南:从静态文档到可执行运维资产 简介:本资源是一份面向IT运维工程师、数据中心管理员及电力保障技术人员的UPS设备标准化维护保养规程文档,聚焦关键基础设施供电连续性保障场景。文档系统覆盖UPS工作原理(含整流/逆变双变换机制、IGBT高频转换、维修旁路切换逻辑)… · 2026/9/23 15:06:48
Python实现AASM合规的EEG睡眠分期深度学习流水线 简介:本资源是一套基于Python实现的深度神经网络睡眠分期检测完整研究方案,面向生物医学工程、人工智能交叉领域的小白与进阶学习者,适用于本科毕设、课程设计及医疗AI方向的工程实训项目。资源包共2005个文件,主体为1893个Python… · 2026/9/23 15:06:48
从单体到 Serverless:我踩过的 4 种架构模式的坑,一张表帮你选型 2023 年我们团队把一个跑了 6 年的单体应用拆成了 27 个微服务,18 个月后又把其中 9 个合并了回去。这不是一次失败的架构演进,而是一次代价 4 个人月、但值得的学费。这篇文章把单体、SOA、微服务、Serverless 四种模式的适用边界、代码组织方式和真实踩… · 2026/9/23 15:06:48
定制柜背板 5 毫米、9 毫米、18 毫米,各用在哪 背板用 5 毫米、9 毫米还是 18 毫米,先看柜子挂在哪个房间、柜深多少、跨度多长,不是越厚越合适。这是做海口全屋定制时容易被一句话带过去的构件,也容易被"加厚就是升级"的直觉带偏。欧派大家居在海口是有实体门店的连锁体系&… · 2026/9/24 4:28:04
nginx-ui MCP 配置管理工具详解:让 AI Agent 安全读写 Nginx 配置文件 后端前端运维MCP 服务 【免费下载链接】nginx-ui Yet another WebUI for Nginx 项目地址: https://gitcode.com/gh_mirrors/ngi/nginx-ui 点击查看 免费下载 导读
本文聚焦 nginx-ui 内置的 MCP(Model Context Protocol)配置管理模块&#… · 2026/9/24 4:28:04
# 从单智能体到多智能体:这是为什么 搜索“site:ijcai.org 2026 large language model multi-agent”,DuckDuckGo 返回 2024 年的综述和 2025 年的 L2M2 框架论文。这个结果并不意外——LLM 多智能体系统从提出到工程落地,一直是 IJCAI 最拥挤的赛道之一。与其追逐新名词,不如拆… · 2026/9/24 4:27:58
LPC2388实战指南:AMBA总线与ARM7嵌入式开发深度解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 4:27:58
ESP8266/ESP32多屏驱动方案:共享总线加分时片选实现MAX7219点阵屏控制 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 4:27:52
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44