RFC 草案:为 ext/openssl 增加 DTLS 流传输支持(In Draft)

风静大大_5236

风静大大_5236

2026-11-12

467人浏览

原创

php 的流传输层可以把 tcp 连接加密成 tls,却始终没有一个官方手段去加密 udp——直到 2026-11-10,wiki.php.net 的 rfc 索引页在「in draft」区新增了一条草案:dtls support in ext/openssl。草案提议在 ext/openssl 中引入 dtls://、dtlsv1.2:// 与 dtlsv1.3:// 三种流传输,让 stream_socket_client()、stream_socket_server() 能像使用 tls:// 一样使用 dtls。当前状态为 draft、版本 0.1,讨论串与投票串均标注 tbd,尚未在 php internals 邮件列表公布。

wiki.php.net RFC 页面

▲ wiki.php.net RFC 页面

草案要解决的问题:UDP 流量没有原生加密手段

DTLS 是 TLS 针对数据报的改造版本,由 RFC 6347(DTLS 1.2)与 RFC 9147(DTLS 1.3)定义,被大量物联网与实时通信协议当作默认的安全层:CoAP 与 LwM2M 用 5684 端口的 DTLS 保护设备通信,WebRTC 数据通道、SIP、各类远程接入隧道以及加密 syslog 也都建立在它之上。

问题在于 PHP 端一直没有对应能力。现有 ext/openssl 只把 TLS 接到 tcp:// 流上,一旦业务需要与 DTLS 端点对话,开发者只有两条路:起一个外部进程(openssl s_client、stunnel 之类)做转发,或者自己写 C 扩展。两种做法都把复杂度推给了部署环节,也让 PHP 在 CoAP 服务器、WebRTC 信令以外的场景里缺位。草案作者 Gianfrancesco Aurecchia 给出的目标很直接:把这些能力做进内核自带的扩展,用法与 tls:// 保持一致。

新增的传输协议与调用方式

草案计划注册三种传输协议名,区别只在允许协商的 DTLS 版本:dtls:// 同时允许 DTLS 1.2 与 1.3(1.3 需底层 OpenSSL 支持),dtlsv1.2:// 只允许 1.2,dtlsv1.3:// 只允许 1.3 且仅在该 OpenSSL 支持时注册。客户端与服务端都可使用。

<?php $ctx = stream_context_create(['ssl' => ['cafile' => '/etc/ssl/ca.pem']]);
$client = stream_socket_client('dtls://example.com:5684', $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $ctx);

fwrite($client, "ping");      // 一次 fwrite() 对应一条 DTLS 记录
echo fread($client, 1500);    // 一次 fread() 返回一个数据报

?>

▲ 草案正文中的客户端示例

与 tls:// 一样,DTLS 也支持「先建明文流、再升级加密」。草案把 udp:// 一并交给 ext/openssl 提供(现状是 tcp:// 由该扩展提供),于是已有的 UDP 流可以用 stream_socket_enable_crypto() 就地升级:

<?php $client = stream_socket_client('udp://example.com:5684', $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $ctx);
stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_DTLS_ANY_CLIENT);

?>

配套新增六个常量:STREAM_CRYPTO_METHOD_DTLSv1_2_CLIENT、STREAM_CRYPTO_METHOD_DTLSv1_3_CLIENT、STREAM_CRYPTO_METHOD_DTLS_ANY_CLIENT 及对应的三个 _SERVER 版本,用于在 stream_socket_enable_crypto() 与 ssl 上下文的 crypto_method 中显式指定协议族。草案里的常量值目前写作 UNKNOWN,属占位状态。

wiki.php.net RFC 索引页

▲ wiki.php.net RFC 索引页

实现方式:按层拆分,不与 TLS 分叉

草案的 Implementation 字段指向 php/php-src 的 PR #22638,标题为「ext/openssl: add a dtls:// stream transport. Open as Draft.」。该 PR 已迭代 8 次提交,改动 43 个文件、+4719/−605 行,目前仍标记为 Draft。按 PR 描述,实现刻意按「层」而不是按「协议」切分,避免为 DTLS 复制一套选项解析与 IO 循环:

密文传输集中在 xp_bio.c。OpenSSL 自身不做 IO,其 BIO 从一个接收队列取记录、向连接持有的发送队列追加,流在每次 SSL_*() 调用前后把密文搬进搬出。这样任何 OpenSSL 调用都不会阻塞,socket 在加密建立后保持非阻塞,阻塞语义由单调时钟截止时间模拟等待来还原。传输可以是流自身的 socket,也可以是新增的 inner_stream 上下文选项指定的任意流,于是「TLS over 任意流」与「DTLS over 任意流」同时成立。

流实现合并在 xp_ssl.c:数据报协议名只负责挑选 DTLS 方法与版本范围,证书校验、SNI、ALPN、PSK、会话、early data、密码套件、安全等级、元数据等全部与 TLS 共用一套代码,旧的 gettimeofday() 轮询和描述符模式切换被删除。服务端逻辑单独放在 xp_dtls.c:一个 UDP socket 承载所有 peer,按对端地址把数据报路由到各自连接,新 peer 的握手走 cookie 交换(SSL_OP_COOKIE_EXCHANGE、带时间戳的 HMAC cookie、pending 上限与超时),完成握手的连接以共享该 socket 的流形式交给 stream_socket_accept()。值得注意的是它既不用 DTLSv1_listen()(仅支持 1.2、仅单 peer),也不用 OpenSSL 4.1 才有的 listener API,因此从 OpenSSL 1.1.1 起都能工作。

php-src 实现提案 PR

▲ php-src 实现提案 PR

语义与向后兼容性代价

DTLS 在语义上向 tls:// 看齐:verify_peer_name 与 verify_peer 相互独立,peer_fingerprint 在关闭 verify_peer 时依然生效,会话通过 session_new_cb 捕获,握手在 stream_socket_accept() 内部完成。客户端 dtls:// 会协商 1.2 或 1.3;服务端只有在显式指定 crypto_method 时才提供 1.3,因为在 OpenSSL listener 之外,服务端无法在首个 flight 之前验证对端地址。新增的 ssl 上下文选项还包括 dtls_link_mtu、dtls_max_pending(默认 256)、dtls_pending_timeout(默认 30 秒),以及按 RFC 5705 导出密钥材料的 keying_material_label 与 keying_material_length。

SSL Certificate Checker
SSL Certificate Checker

SSL/TLS 证书到期检查器和域名健康监控。检查证书到期、颁发者信息、SAN 条目及证书链有效性,适用于单个或多个域名。

下载

兼容性代价写在 Backward Incompatible Changes 一节里,共两处。其一是新增的六个全局常量理论上可能与用户自定义常量重名——作者的检索结论是没有项目定义过 STREAM_CRYPTO_METHOD_DTLS*。其二是更实际的一处:ext/openssl 加载后 udp:// 流由该扩展创建,stream_get_meta_data() 返回的 stream_type 会从 udp_socket 变成 udp_socket/dtls,正如今天的 tcp:// 报告的是 tcp_socket/ssl。作者在 GitHub 上检索到 143 处把 stream_type 与字符串 udp_socket 做严格比较的代码,其中包括 symfony/polyfill,这类比较会因此失效。

RFC 9147 规范页

▲ RFC 9147 规范页

当前状态与后续观察点

这份文档还远未成型。页面头部标注 Version 0.1、Status Draft,Proposal 主章节下的 Server 与 Examples 两节均为 TBD,Open Issues、Future Scope、Implementation 也还是占位;Voting Choices 里的投票表格显示 0/0/0 且标注 poll closed,属于模板未填,不能解读为已有投票结果。索引页把 In Draft 区定义为「尚未在 PHP internals 邮件列表公布」的早期草案,因此它既没有进入讨论,也没有进入投票。

时间线上有一处需要说明的出入:RFC 页面头部 Date 字段写作 2026-11-12,而索引页条目与 wiki 的 Recent Changes 显示该页创建于 2026-11-10、最后修改于 2026-11-10T21:25:43+00:00。本文按官方页面的实际创建与修改时间记录,不对 Date 字段做外推。若草案继续推进,下一个可观察节点是它从 In Draft 转入 Under Discussion、讨论串与投票串由 tbd 变成真实链接;由于这是主投票,需 2/3 多数通过,目标版本写作「next PHP 8.x」,尚未绑定具体小版本。草案阶段不宜据此做升级或兼容性结论,但把 stream_type 与 udp_socket 做严格比较的代码,值得提前自查一遍。

关键信息

项目 内容
类目 RFC 与需求
状态 Draft(Version 0.1,In Draft 区,未公布讨论)
提案人 Gianfrancesco Aurecchia(gianfri@aurecchia.it)
创建时间 2026-11-10(页面 Last modified 2026-11-10T21:25:43+00:00)
新增传输 dtls://、dtlsv1.2://、dtlsv1.3://(客户端与服务端)
关联编号 RFC: dtls_support_in_ext_openssl;php/php-src PR #22638
影响范围 ext/openssl 流传输层与 main/streams;未绑定具体 PHP 版本
兼容性影响 udp:// 流的 stream_type 变为 udp_socket/dtls;新增 6 个 STREAM_CRYPTO_METHOD_DTLS* 常量
投票门槛 主投票需 2/3 多数;讨论串、投票串均为 tbd
核验状态 已官方确认(wiki.php.net 页面与 php-src PR 双向核对)

来源:https://wiki.php.net/rfc/dtls_support_in_ext_openssl

来源:https://wiki.php.net/rfc

来源:https://github.com/php/php-src/pull/22638

来源:https://www.rfc-editor.org/rfc/rfc9147

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

12704

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

7301

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

2255

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

4608

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

5314

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

4191

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

6057

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

4762

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

12522

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
《20天入门精通PHP》视频教程
《20天入门精通PHP》视频教程

共200课时 | 49.5万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 0.1万人学习