ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

libwebsockets Secure Streams policy2c:JSON 策略到 C 结构体的离线转换工具

libwebsockets Secure Streams policy2c:JSON 策略到 C 结构体的离线转换工具 人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载本篇文章讲解 libwebsocketslwsSecure Streams 体系中一个特殊而实用的工具lws-minimal-secure-streams-policy2c。它的作用是把一份以 JSON 书写的 Secure Streams 策略从标准输入读入并解析然后在标准输出上生成一份可直接参与编译的 C 结构体源码。这样在那些内存受限、无法在运行时解析动态 JSON 策略的嵌入式平台上依然可以继续用 JSON 维护和演进策略再借助本工具把策略烧录成固件里的静态数据。读完本文你将掌握这个转换工具的使用方式、生成产物的结构、以及它如何与LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY静态策略模式配合实现一份 JSON多端部署的落地路径。这个工具解决什么问题Secure Streams 是 lws 提供的网络 API它的设计把载荷与元数据严格分离连接的目标地址、TLS 信任链、甚至所使用的协议都被收纳进一份策略数据库policy database应用代码只负责收发载荷与接收连接状态回调。策略通常以 JSON 形式在lws_context创建时传入甚至可以从远端更新。但并非所有平台都适合动态解析 JSON。对于 Flash/RAM 紧张的嵌入式目标运行时解析 JSON 策略既不划算也有风险。policy2c 正是为这一场景准备的你仍然用 JSON 维护和编写策略便于阅读、审查、版本管理在 PC/构建机上运行本工具把 JSON 一次性地转换为可编译的 C 结构体生成的 C 代码直接包含进固件目标设备无需 JSON 解析器即可使用 Secure Streams。从源码注释可以看到它定位的描述Its useful if your platform is too space-constrained for a JSON policy and needs to build a static policy in C via LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY... this way you can still create and maintain the JSON policy but implement it directly as C structs in your code.见 minimal-secure-streams.c 文件头注释。依赖与构建编译前提policy2c 自身需要在支持完整协议角色的 lws 构建上编译因为它必须能解析任意策略内容——无论是 HTTP/1、HTTP/2、WebSocket 还是 MQTT 的 streamtype。工具文档明确指出它依赖LWS_ROLE_H1、LWS_ROLE_H2、LWS_ROLE_WS与LWS_ROLE_MQTT四个构建选项。这一依赖也反映在它的 CMakeLists.txt 中require_lws_config(LWS_ROLE_H1 1 requirements) require_lws_config(LWS_ROLE_H2 1 requirements) require_lws_config(LWS_ROLE_MQTT 1 requirements) require_lws_config(LWS_WITHOUT_CLIENT 0 requirements) require_lws_config(LWS_WITH_SECURE_STREAMS 1 requirements) require_lws_config(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY 0 requirements)其中最后一行很有意思policy2c 作为生成器工具运行在 PC 上因此它自身不需要以静态策略模式构建相反静态策略模式LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY1是它生成物所服务的下游目标形态。构建命令与绝大多数 lws minimal example 相同在示例目录中直接执行$ cmake . make构建产物是可执行文件lws-minimal-secure-streams-policy2c。使用方式命令行参数命令行选项含义-d loglevel调试输出详细程度十进制例如-d15基本用法工具从stdin读取 JSON 策略向stdout输出等价的 C 结构体源码$ cat mypolicy.json | lws-minimal-secure-streams-policy2c (on stdout) static const uint32_t _rbo_bo_0[] { 1000, 2000, 3000, 5000, 10000, }; static const lws_retry_bo_t _rbo_0 { .retry_ms_table _rbo_bo_0, .retry_ms_table_count 5, .conceal_count 5, .secs_since_valid_ping 30, .secs_since_valid_hangup 35, .jitter_percent 20, }; static const uint8_t _ss_der_amazon_root_ca_1[] { /* 0x 0 */ 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, /* 0x 8 */ 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x06, /* 0x 10 */ 0x6C, 0x9F, 0xCF, 0x99, 0xBF, 0x8C, 0x0A, 0x39, /* 0x 18 */ 0xE2, 0xF0, 0x78, 0x8A, 0x43, 0xE6, 0x96, 0x36, /* 0x 20 */ 0x5B, 0xCA, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, ...重定向即可保存$ cat mypolicy.json | lws-minimal-secure-streams-policy2c static-policy.h转换过程与源码级原理整体流程从 minimal-secure-streams.c 的main()可以看出转换的大致步骤创建lws_contextCONTEXT_PORT_NO_LISTEN即不监听任何端口调用lws_ss_policy_parse_begin(context, 0)开始一次策略解析会话循环从 stdinread()数据块逐块交给lws_ss_policy_parse()做增量解析若返回错误且不是LEJP_CONTINUE表示数据尚未完整需要继续喂入则视为解析失败并退出解析完成后通过lws_ss_policy_get(context)取得内存中的策略对象链表逐类遍历并输出对应的 C 结构体。过程中还会在输出头部把原始 JSON 原样回显并用#if 0 ... #endif包起来同时打印 Original JSON size: xxx 提示原始策略的体积结尾会打印一段估计的 C 侧内存占用例如/* estimated footprint 10720 (when sizeof void * 8) */这个估计值由工具内部累加各结构体sizeof与证书 DER 长度得到方便评估静态策略的最终成本。标识符清洗purify_csymbolJSON 里的名称streamtype、metadata 名、证书名、auth 名、trust store 名等要变成合法的 C 标识符。工具用purify_csymbol()把任何既不是字母也不是数字的字符替换成下划线_例如api.amazon.com这类名字在生成的结构体命名中会以_ss_ts_api_amazon_com的形式出现。这是从源码中可以明确确认的实现事实。去重机制转换器在遍历策略时维护了三个已见过映射见 minimal-secure-streams.c 中的rbomap、trustmap、certmapretry/backoff 对象多个 streamtype 往往共享同一个retry: default重试方案工具只输出一份_rbo_NN 为递增序号trust store同一信任库被多个 streamtype 引用时只生成一份_ss_ts_namex.509 证书证书按名称去重DER 字节只输出一份_ss_der_name数组并伴随一个_ss_x509_name包装结构。其余 streamtype 之间通过next指针串成链表所有指针在输出时都指向已生成的static const对象因此最终产物是一批相互引用的编译期常量天然适合放进只读存储器。各类生成物的结构从工具源码与仓库内已生成的 static-policy.h 可以总结出产物涵盖的类型生成物对应 JSON 概念说明_md_streamtype_namestreamtype 的metadata条目lws_ss_metadata_t数组含 name、可选默认值、长度等_rbo_bo_n/_rbo_nretry[].backoff / conceal / jitterpc等uint32_t延时表 lws_retry_bo_t重试/退避结构_ss_der_cert/_ss_x509_certcerts中的 base64 DER 证书uint8_t字节数组 lws_ss_x509_t包装_ss_ts_storetrust_storeslws_ss_trust_store_t内含ssx509[]证书指针数组streamtype_http_respmaphttp_resp_mapHTTP 响应码到 SS 状态的映射表_ssau_nameauth条目lws_ss_auth_tname/type/streamtype/blob_index_ssp_streamtypes中的每个 streamtypelws_ss_policy_t策略结构含协议联合体u.http/u.mqtt其中lws_ss_policy_t的u联合体按协议分支输出H1 / H2 / WS输出.http.method/.url/.multipart_name/.auth_preamble/.respmap/.blob_header/.resp_expect/.fail_redirect等若协议是 WS还会嵌套输出.u.ws.subprotocol/.binaryMQTT输出.mqtt.topic/.subscribe/.will_*/.birth_*/.keep_alive/.qos/.clean_start/.aws_iot/.retain等其余协议索引会触发错误退出unknown ss protocol index这提示工具只支持这四类协议角色的策略内容。streamtype 结构最后还会输出timeout_ms、flags、priority、port、metadata_count、protocol、client_cert、trust以及retry_bo指针引用如果 lws 构建时启用了LWS_WITH_SECURE_STREAMS_AUTH_SIGV4还会额外输出aws_region/aws_service字段见源码中该宏条件编译块。输出链表的头结点在最后以宏形式标记出来#define _ss_static_policy_entry _ssp_api_amazon_com_auth这个宏正是静态策略模式下应用通过info.pss_policies _ss_static_policy_entry;挂载给lws_context的入口。产物如何被下游使用static policy 模式配套示例 minimal-secure-streams-staticpolicy仓库里有一个与 policy2c 直接配套的示例 minimal-secure-streams-staticpolicy它演示了用 policy2c 生成的静态策略跑真实 HTTP 客户端的完整链路应用访问https://warmcat.com/并读取其 index.html。该目录下有三个关键文件static-policy.json原始 JSON 策略内含 retry 方案、多张 CA 证书、trust store、以及mintest、avs_*、mqtt_test*、captive_portal_detect等一批 streamtypestatic-policy.h由 policy2c 从该 JSON 生成的 C 头文件约 1500 行头部#if 0块中嵌着原始 JSON 与 Original JSON size: 15493文件末尾即为_ssp_*策略链表与#define _ss_static_policy_entry _ssp_api_amazon_com_authminimal-secure-streams.c应用本体直接#include static-policy.h。在应用侧静态策略通过lws_context_creation_info的pss_policies字段挂载info.pss_policies _ss_static_policy_entry; info.options LWS_SERVER_OPTION_EXPLICIT_VHOSTS | LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;然后照常创建mintest类型的 Secure Streamssi.streamtype mintest; lws_ss_create(context, 0, ssi, NULL, NULL, NULL, NULL);在LWSSSCS_CREATING状态里通过lws_ss_set_metadata()设置uptag、ctype等元数据再lws_ss_client_connect()发起连接最后在 rx 回调中收到页面载荷。其 CMakeLists.txt 也印证了静态策略模式是构建前提require_lws_config(LWS_ROLE_H1 1 requirements) require_lws_config(LWS_WITHOUT_CLIENT 0 requirements) require_lws_config(LWS_WITH_SECURE_STREAMS 1 requirements) require_lws_config(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY 1 requirements)注意这个下游示例只需要LWS_ROLE_H1而生成它的 policy2c 却要求四种角色——这正是生成端全能力、运行端按需裁剪的典型分工。运行输出示例README 中记录了该静态策略客户端的典型运行日志$ ./lws-minimal-secure-streams-staticpolicy [2020/03/26 15:49:12:6640] U: LWS secure streams static policy test client [-dverb] [2020/03/26 15:49:12:7067] N: lws_create_context: using ss proxy bind (null), port 0, ads (null) [2020/03/26 15:49:12:7567] N: lws_tls_client_create_vhost_context: using mem client CA cert 914 ... [2020/03/26 15:49:13:9625] N: ss_api_amazon_auth_rx: acquired 588-byte api.amazon.com auth token, exp 3600s [2020/03/26 15:49:13:9747] U: myss_state: LWSSSCS_CREATING, ord 0x0 [2020/03/26 15:49:13:9774] U: myss_state: LWSSSCS_CONNECTING, ord 0x0 [2020/03/26 15:49:14:1897] U: myss_state: LWSSSCS_CONNECTED, ord 0x0 [2020/03/26 15:49:14:1926] U: myss_rx: len 1520, flags: 1 ... [2020/03/26 15:49:14:2136] U: myss_rx: len 0, flags: 2 [2020/03/26 15:49:14:2137] U: myss_state: LWSSSCS_QOS_ACK_REMOTE, ord 0x0 [2020/03/26 15:49:14:2170] U: myss_state: LWSSSCS_DISCONNECTED, ord 0x0 [2020/03/26 15:49:14:2192] U: myss_state: LWSSSCS_DESTROYING, ord 0x0 [2020/03/26 15:49:14:2282] U: Completed: OK可以看到日志中 TLS vhost 使用的 CA 证书来自mem内存中的静态 DER 数组即 policy2c 生成物且整个流程经历了CREATING → CONNECTING → CONNECTED → QOS_ACK_REMOTE → DISCONNECTED → DESTROYING的完整 Secure Streams 状态机。构建模式说明LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY模式下 lws 不会构建 JSON 策略解析器若项目其他部分也用不到 LEJP 解析器还可以顺带关闭 LEJP 选项再省下约 2KB 空间这一数量说明来自 libwebsockets 自带的 Secure Streams 总览文档 lib/secure-streams/README.md 中 Using static policies 一节。这正是 policy2c 存在意义的量化注脚。JSON 策略关键字段速览由于 policy2c 的输入即 Secure Streams JSON 策略掌握输入格式才能用好该工具。以下字段来自 lib/secure-streams/README.md 的 JSON Policy Database 一节与仓库内 static-policy.json 相互印证字段作用release/product/schema-version策略版本、适用产品、解析器最低版本要求retry[]重试/退避方案集合内部含backoff逐次毫秒延时数组、conceal向上层隐藏的失败次数65535 表示永不放弃、jitterpc延时随机抖动百分比防重试风暴等certs校验所需的 CA 证书格式为 base64 DER即 PEM 首尾行之间的内容trust_stores由certs组成的命名证书链每个条目会创建对应命名的 vhost TLS 上下文auth认证方案映射name/type/streamtype/blob如 sigv4s各 streamtype 的策略定义数组是转换的主体streamtype 常用成员包括endpoint支持${metadata}运行时替换前缀表示 Unix Domain Socket、port、protocolh1/h2/ws/mqtt/raw、tls、tls_trust_store、retry、opportunistic、nailed_up、timeout_ms、metadata[]、HTTP 类http_method/http_url/http_expect/http_fail_redirect/http_auth_header/http_auth_preamble/http_resp_map/http_multipart_*、WS 类ws_subprotocol/ws_binary、MQTT 类mqtt_topic/mqtt_subscribe/mqtt_qos/mqtt_keep_alive/mqtt_will_*/mqtt_clean_start等。转换器对这些字段的 C 输出分支与上述列表一一对应。最佳实践与注意事项工具跑在构建机不在目标机policy2c 需要在带全角色H1/H2/WS/MQTT的 lws 构建下编译运行其输出才参与固件编译。目标设备侧则按需启用LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY只编译必需的协议角色。一次转换多处复用policy2c 已做过去重优化共享的 retry 方案、trust store、证书只会生成一份常量多个 streamtype 通过指针引用降低最终体积。JSON 仍是唯一事实来源把static-policy.json纳入版本管理改策略时只改 JSON、重新运行转换避免手改 C 产物——这既保持了 JSON 的可读可审也保证生成物与策略严格同步。关注体积预算工具会回显原始 JSON 字节数并在结尾打印估计 footprint如estimated footprint 10720可用于静态策略的 ROM 成本评估。协议角色对齐输入策略中出现ws或mqttstreamtype 时policy2c 的构建必须具备对应角色否则解析会失败源码在解析错误时输出lws has WITH_ROLEs for whats in the JSON?的提示。相关资源工具本体minimal-secure-streams.c 与 CMakeLists.txt静态策略配套示例minimal-secure-streams-staticpolicy其 static-policy.h 是 policy2c 的真实产出样例static-policy.json 是对应输入Secure Streams 总览与 JSON 策略字段详解lib/secure-streams/README.md相关 CMake 配置项在 lib/secure-streams/CMakeLists.txt 与 CMakeLists.txt 中定义赞分享人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载相关推荐libwebsockets Secure Streams 静态策略示例实战从 JSON 策略到 C 代码的完整链路libwebsockets Secure Streams 静态策略示例实战从 JSON 策略到 C 代码的完整链路 本篇指南围绕 libwebsockets人工智能AI Agent多模态语音AI 应用Xinference 部署 llama-3-instruct 完全指南模型规格、量化选项与多引擎启动命令详解Xinference 部署 llama 3 instruct 完全指南模型规格、量化选项与多引擎启动命令详解 本文基于 Xinference 内置模型文档 l人工智能AI Agent多模态语音AI 应用仓颉宏原理实战hystrix-cj的ProtectedResrouce如何用Token插码实现零侵入熔断仓颉宏原理实战hystrix cj的ProtectedResrouce如何用Token插码实现零侵入熔断 hystrix cj 是一个面向仓颉语言的熔断降级人工智能AI Agent多模态语音AI 应用上一篇UPNG.js 开源项目教程下一篇Moveable 开源项目教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表