
物联网消息队列后端【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mosquit/mosquitto点击查看免费下载导读本文围绕 Mosquitto 2.0.14 这一 bugfix 版本展开逐一剖析其包含的三项关键修复Broker 端 MQTT v5 桥接重连时未遵守 receive-maximum 的问题以及客户端库中mosquitto_topic_matches_sub2()长度参数失效与 mosquittopp 头文件subscribe_callback声明错误。通过结合本仓库的 bridge.c、util_topic.c、mosquittopp.cpp 等源码读者不仅能了解 2.0.14 修复了什么更能理解这些修复背后的 MQTT 协议机制与实现细节从而在升级、桥接配置和客户端开发中做出正确决策。版本概览一次聚焦的 bugfix 发布Mosquitto 2.0.14 于 2021-11-17 发布是 2.0.x 系列的一次纯缺陷修复bugfix版本不引入新功能。根据仓库 ChangeLog.txt 的记载本次修复分两部分BrokerBroker修复桥接在 MQTT v5 重连时不遵守 receive-maximum 的问题。客户端库Client library修复mosquitto_topic_matches_sub2()未使用长度参数的问题对应 issue #2364修复 mosquittopp.h 中错误的subscribe_callback对应 issue #2367。发布公告原文见 www/posts/2021/11/version-2-0-14-released.md。这三个修复分别涉及桥接连接的流量控制、客户端库的 API 正确性与 C 绑定层的回调签名下面逐项展开。Broker 修复桥接重连时正确遵守 MQTT v5 receive-maximum问题背景receive-maximum 与 QoS 1/2 流量控制在 MQTT v5 协议中CONNECT 报文可以携带Receive Maximum属性用于限制对端此处为桥接所连的远端 Broker能够同时发送的、尚未收到 PUBACK/PUBCOMP 确认的 QoS 1 和 QoS 2 报文数量。这一属性与 Broker 配置项max_inflight_messages共同构成了桥接链路上的在途消息配额控制。在 mosquitto.conf 中bridge_receive_maximum的说明如下# If the bridge is using MQTT v5.0 then use bridge_receive_maximum to # limit the number QoS 1 or 2 messages that can be in-flight at once. # Must be 1-65535. Defaults to the same value as max_inflight_messages, # which defaults to 20. #bridge_receive_maximum 20也就是说该配置仅在桥接使用 MQTT v5 时生效取值范围 1–65535默认继承max_inflight_messages其默认值为 20。修复内容重连时属性丢失2.0.14 之前的问题是当桥接因为网络中断等原因触发重连时重新发送的 CONNECT 报文没有携带正确的 Receive Maximum 属性导致远端 Broker 不受在途配额约束可能向桥接一次性涌入超过其处理能力的 QoS 1/2 报文。修复后的行为可以从 src/bridge.c 的两处bridge__connect系列函数中得到印证。在连接建立并发送 CONNECT 报文前代码会构造 MQTT 属性链表if(context-bridge-receive_maximum ! 0){ receive_maximum.value.i16 context-bridge-receive_maximum; receive_maximum.identifier MQTT_PROP_RECEIVE_MAXIMUM; receive_maximum.property_type MQTT_PROP_TYPE_INT16; receive_maximum.client_generated false; receive_maximum.next properties; properties receive_maximum; }见 src/bridge.c 与 src/bridge.c随后该属性链表随send__connect()一并发出。其中context-bridge-receive_maximum这一字段定义于 src/mosquitto_broker_internal.h类型为uint16_t。配置解析侧参数校验bridge_receive_maximum的解析在 src/conf.c 完成可以看到严格的取值范围校验}else if(!strcmp(token, bridge_receive_maximum)){ ... if(conf__parse_int(token, bridge_receive_maximum, tmp_int, saveptr)) return MOSQ_ERR_INVAL; ... log__printf(NULL, MOSQ_LOG_ERR, Error: bridge_receive_maximum must be greater than 0.); ... log__printf(NULL, MOSQ_LOG_ERR, Error: bridge_receive_maximum must be lower than %u., UINT16_MAX); ... cur_bridge-receive_maximum (uint16_t)tmp_int; }小于等于 0 或超过 65535UINT16_MAX都会被拒绝并返回MOSQ_ERR_INVAL这也解释了配置注释中Must be 1-65535的约束来源。实操建议在桥接配置中使用 MQTT v5 时建议显式设置该值避免重连后流量控制失效connection remote-mqtt5-broker address broker.example.com:1883 bridge_protocol_version mqttv50 bridge_receive_maximum 20需要说明的是2.0.14 之前重连时未携带 receive-maximum的行为源于连接重建路径对属性的重复构造不一致本次修复确保无论是首次连接还是断线重连CONNECT 报文都携带相同的 Receive Maximum 属性。客户端库修复一mosquitto_topic_matches_sub2()正确使用长度参数问题背景带长度参数的匹配 APImosquitto_topic_matches_sub2()是 Mosquitto 客户端库提供的带显式长度参数的订阅匹配函数其原型位于 lib/util_topic.cBROKER_EXPORT int mosquitto_topic_matches_sub2( const char *sub, size_t sublen, const char *topic, size_t topiclen, bool *result)与不带长度的mosquitto_topic_matches_sub()lib/util_topic.c相比_sub2允许调用者传入包含二进制数据或非 NUL 结尾的字符串而无需依赖strlen。该符号在 lib/linker.version 中导出。修复内容长度参数未生效2.0.14 之前mosquitto_topic_matches_sub2()的实现忽略了传入的sublen与topiclen内部仍按 C 字符串NUL 结尾方式遍历导致传入的子串/主题中若含空字节匹配会提前终止调用者明明指定了长度函数却可能越界读取或匹配范围与预期不符。修复后的实现彻底改为基于长度游标遍历核心逻辑可见 lib/util_topic.cspos 0; tpos 0; while(spos sublen){ ... if(tpos topiclen || sub[spos] ! topic[tpos]){ if(sub[spos] ){ /* Check for bad foo or a/foo subscription */ if(spos 0 sub[spos-1] ! /){ return MOSQ_ERR_INVAL; } ... }else if(sub[spos] #){ ... } } ... }同时入口参数校验也更严格lib/util_topic.cif(!result) return MOSQ_ERR_INVAL; *result false; if(!sub || !topic || !sublen || !topiclen){ return MOSQ_ERR_INVAL; }即sub、topic任一为空或长度为零时返回MOSQ_ERR_INVAL。此外该实现完整保留了 MQTT 通配符语义与合法性检查包括$开头的系统主题与普通主题互不匹配lib/util_topic.c必须独占一个层级如foo/合法而foo、foo非法返回MOSQ_ERR_INVAL#必须是订阅的最后一个字符如foo/#合法而foo#、#foo非法主题中出现/#属于非法输入支持foo匹配foo/#、foo/bar匹配foo//#等边界情形。使用示例#include mosquitto.h #include stdbool.h #include stdio.h int main(void) { bool result false; const char *sub sensors//temperature; const char *topic sensors/room1/temperature; int rc mosquitto_topic_matches_sub2( sub, strlen(sub), topic, strlen(topic), result); if(rc MOSQ_ERR_SUCCESS result){ printf(topic matches subscription\n); } return 0; }对使用该 API 做 ACL 或消息过滤的开发者也应注意长度参数现在被完整尊重因此传入的缓冲区长度必须与实际数据一致不能再依赖多传一点没关系的旧行为。客户端库修复二mosquittopp.h 中错误的subscribe_callback问题背景C 绑定层Mosquitto 的 C 绑定libmosquittopp在 lib/cpp/mosquittopp.cpp 中提供了对 C 库的封装。其中subscribe_callback是一个一键订阅辅助函数内部直接转调 C API 的mosquitto_subscribe_callback()lib/cpp/mosquittopp.cppmosqpp_EXPORT int subscribe_callback( int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), void *userdata, const char *topic, int qos, const char *host, int port, const char *clientid, int keepalive, bool clean_session, const char *username, const char *password, const struct libmosquitto_will *will, const struct libmosquitto_tls *tls) { return mosquitto_subscribe_callback( callback, userdata, topic, qos, host, port, clientid, keepalive, clean_session, username, password, will, tls); }修复内容头文件声明与实现不一致2.0.14 之前include/mosquittopp.h 中subscribe_callback的声明与 lib/cpp/mosquittopp.cpp 的实现存在签名不一致参数类型或顺序错误导致使用 C 绑定调用该函数的用户在编译期或运行期出现错误行为。2.0.14 将头文件中的声明修正为与实现一致的正确签名。从 src 的调用链 还可以看到mosquittopp 在构造与reinitialise()时统一通过mosquitto_callbacks_set()将各回调含subscribe/subscribe_v5与 C 层绑定这与subscribe_callback这类一次性辅助函数是两条不同的订阅路径二者在 2.0.14 中均已校验正确。使用提示使用 C 绑定的用户应确保回调函数签名与声明一致例如#include mosquittopp.h static int on_subscribe_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message) { // 处理订阅到的消息 return 0; } int main() { return subscribe_callback( on_subscribe_message, nullptr, test/topic, 1, localhost, 1883, nullptr, 60, true, nullptr, nullptr, nullptr, nullptr); }升级到 2.0.14 后该辅助函数的调用行为与头文件声明完全一致不再出现签名错配问题。升级与验证获取与构建Mosquitto 2.0.14 可以从仓库历史标签获取源码或通过各发行版包管理器安装。源码构建方式遵循 README-compiling.md 的说明Broker、客户端库与工具均可在仓库根目录通过 Makefile 或 CMake 构建。2.0.14 为 2.0.x 系列内的 bugfix 版本对配置格式无破坏性变更升级时现有mosquitto.conf可继续沿用。验证要点升级后建议重点验证以下场景桥接流量控制配置bridge_protocol_version mqttv50与bridge_receive_maximum后人为断开桥接并观察重连远端 Broker 日志中应能看到重连后的 CONNECT 报文携带 Receive Maximum 属性值即bridge_receive_maximum。主题匹配对mosquitto_topic_matches_sub2()传入非 NUL 结尾缓冲区或含空字节数据确认匹配结果只受显式长度约束且非法通配符输入正确返回MOSQ_ERR_INVAL。仓库中的主题匹配相关测试可参考 test/broker/03-pattern-matching.py 等用例的匹配语义。C 绑定重新编译使用subscribe_callback的 mosquittopp 程序确认声明与定义一致、编译无警告、运行时回调行为正常。小结Mosquitto 2.0.14 虽然只包含三项修复但每项都直指实际使用中的真实缺陷桥接重连后的 MQTT v5 流量控制失效可能造成远端消息洪泛mosquitto_topic_matches_sub2()忽略长度参数会让依赖该 API 的过滤逻辑产生错误结果mosquittopp 头文件签名错误则直接破坏 C 用户的编译与运行。对于生产环境中使用 MQTT v5 桥接、或调用客户端库主题匹配 API 的用户本次升级属于低成本、高收益的必更版本。若需追踪后续修复可查阅 ChangeLog.txt 中 2.0.14 之后的版本记录。赞分享物联网消息队列后端【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mosquit/mosquitto点击查看免费下载相关推荐Mosquitto 2.0.14 缺陷修复版本解析Bridge 重连 receive-maximum、主题匹配长度参数与 C 回调签名修复Mosquitto 2.0.14 缺陷修复版本解析Bridge 重连 receive maximum、主题匹配长度参数与 C 回调签名修复 导读 Ecli物联网消息队列后端网络/通信Eclipse Mosquitto 1.4.11 发布解析Broker 桥接、WebSocket 与客户端库关键修复详解Eclipse Mosquitto 1.4.11 发布解析Broker 桥接、WebSocket 与客户端库关键修复详解 本篇技术文章以 Eclipse Mo物联网消息队列后端Eclipse Mosquitto 2.0.14 版本发布详解Broker 与客户端库的关键 Bugfix 深度解析Eclipse Mosquitto 2.0.14 版本发布详解Broker 与客户端库的关键 Bugfix 深度解析 Mosquitto 2.0.14 是 E后端消息队列消息路由上一篇如何用精准色彩生成器打造终极色彩方案下一篇终极指南如何使用React瀑布流布局组件快速构建现代化界面创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考