Mbed TLS 常见报错排查

[English]

以下整理了几类 ESP-IDF 中 Mbed TLS 常见的报错日志,对应原因和可能的解决办法。

示例:esp-tls: couldn’t get hostname for :drive.google.com: getaddrinfo() returns 202, addrinfo=0x0

此问题对应的完整 log 往往为:

E (83792) esp-tls: couldn't get hostname for :drive.google.com: getaddrinfo() returns 202, addrinfo=0x0
E (83792) esp-tls: Failed to open new connection
E (83792) transport_base: Failed to open a new connection
E (83802) HTTP_CLIENT: Connection failed, sock < 0

报错分析:

  • getaddrinfo() 解析失败,返回错误代码 202,表示无法解析 drive.google.com,并且 addrinfo=0x0 说明 getaddrinfo() 没有返回有效的 IP 地址。

可能的原因:

  • DNS 解析失败,可能是 DNS 服务器没有回复,或 ESP 没有收到这个回复。

警告

如果同时使用多个 Netif 接口,如 Wi-Fi 和 LTE, 由于 lwIP 无法支持每个 Netif 拥有独立的 DNS 服务器域名,若 DNS 服务器只能被某个 Netif 接口使用,在 DNS 被其他 Netif 接口覆盖时也会出现此错误。

解决方案:

  • 最好使能 lwIP 层的 DNS 调试日志,或通过无线抓包来进一步确认原因。

备注

  1. 使能 lwIP 层的调试日志的方法可参考此 ESP-FAQ

  2. 无线抓包的方法可参考 乐鑫 Wireshark 使用指南

示例:esp-tls-mbedtls: mbedtls_ssl_handshake returned -0x7F00

mbedtls -0x7F00

此问题对应的完整 log 往往为:

E (3968) esp-tls-mbedtls: mbedtls_ssl_handshake returned -0x7F00
E (3968) esp-tls: Failed to open new connection
E (3968) TRANSPORT_BASE: Failed to open a new connection
E (3978) HTTP_CLIENT: Connection failed, sock < 0
E (3978) http_post: http post request failed: ESP_ERR_HTTP_CONNECT
I (3988) http_event_handler: HTTP_EVENT_DISCONNECTED
W (3998) http_event_handler: last esp error code: 0x801a, mbedtls failure: 0x2880

报错分析:

  • mbedtls_ssl_handshake 返回错误码 -0x7F00,通过查询 Mbed TLS 错误码 可以发现原因是 MBEDTLS_ERR_SSL_ALLOC_FAILED。 ESP 可用内存不足导致 Mbed TLS 申请内存失败。

解决方案:

  • 优化 ESP 内存来确保 ESP 最大空闲块足够用来分配给 Mbed TLS。

此类问题往往可以通过查询 Mbed TLS 错误码 获得一些参考,常见的错误码归纳如下:

Mbed TLS 常见错误码

错误名称

错误码

出错原因

解决方法

MBEDTLS_ERR_SSL_ALLOC_FAILED

-0x7F00

内存分配失败

检查内存使用情况,确保有足够可用内存

MBEDTLS_ERR_X509_FATAL_ERROR

-0x3000

证书解析失败

检查证书文件,确保证书格式正确

MBEDTLS_ERR_X509_CERT_VERIFY_FAILED

-0x2700

证书验证失败

确保核心 CA 证书有效,并检查证书链

MBEDTLS_ERR_X509_BAD_INPUT_DATA

-0x2800

证书输入数据无效

确保提供的证书格式正确

MBEDTLS_ERR_SSL_CONN_EOF

-0x7280

连接接收 EOF

检查连接状态,确保对端未意外关闭

MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET

-0x7B00

接收到新的会话票据

确保对端配置了支持会话票据

MBEDTLS_ERR_SSL_INTERNAL_ERROR

-0x6C00

内部错误

确保 Mbed TLS 库配置正确,并启用 debug 查看详细日志

MBEDTLS_ERR_SSL_TIMEOUT

-0x6800

操作超时

增加超时时间或检查网络状况

MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY

-0x7880

对端通知连接关闭

关闭连接,重新建立会话

MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE

-0x7480

需要客户端证书,但未提供

确保客户端提供了正确的证书,并配置了双向认证

MBEDTLS_ERR_SSL_INVALID_RECORD

-0x7200

无效的 TLS 记录

确保通信数据完整可靠,检查是否由于 IN_CONTENT_LENGTH 过小(例如是否为 16 K)而导致问题。同时,请确认对端配置的 TLS 协议相关参数与本端保持一致。

MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE

-0x2080

证书功能不可用

确保开启了相关功能,如需要支持特定加密算法需配置相应选项

MBEDTLS_ERR_X509_INVALID_FORMAT

-0x2180

证书格式无效

确保证书文件为正确格式,并尽量使用 PEM 格式

此外,ESP-IDF 里也将一些 Mbed TLS API 封装后归纳了一些 ESP TLS 返回值,这部分可以参考 ESP TLS 返回值