简体   繁体   English

使用 nRF9160 + Zephyr RTOS 的 CoAP 客户端:代理 URI 长度问题

[英]CoAP Client using nRF9160 + Zephyr RTOS: Proxy-URI length issues

I am developing a CoAP client on the nRF9160 DK, running Zephyr RTOS.我正在 nRF9160 DK 上开发 CoAP 客户端,运行 Zephyr RTOS。 I am having trouble with longer Proxy-URI's;我在使用较长的 Proxy-URI 时遇到问题; short URIs ( 268 characters and below ) work fine and the coap message reaches the server as expected.短 URI( 268 个字符及以下)工作正常,coap 消息按预期到达服务器。 However, messages with longer Proxy-URIs ( 269 characters and above ) fail to go through for some reason.但是,具有较长 Proxy-URI( 269 个字符及以上)的消息由于某种原因无法通过 go。 For example, with the following initialisation:例如,使用以下初始化:

uint8_t tx_coap_buf[2048];
err = coap_packet_init(&request, tx_coap_buf, sizeof(tx_coap_buf), APP_COAP_VERSION, COAP_TYPE_CON, sizeof(next_token), (uint8_t *) &next_token, COAP_METHOD_POST, next_id);
if (err < 0) {
    LOG_DBG("Failed to create CoAP request, %d", err);
    return err;
}

The below (short) works fine以下(短)工作正常

char * proxy_uri = "http://127.0.0.1:3000/abc/europe-xyz1/coap-abc/abc-device/publishEvent?jwt=eyJ0eXAiO";
ssize_t proxy_uri_len = strlen(proxy_uri);
err = coap_packet_append_option(&request, COAP_OPTION_PROXY_URI, proxy_uri, proxy_uri_len);
if (err < 0) {
    LOG_DBG("Failed to create CoAP request, %d", err);
    return err;
}

But this one (longer) doesn't, even though err returns as 0.但是这个(更长的)没有,即使 err 返回为 0。

char * proxy_uri = "http://127.0.0.1:3000/abc/europe-xyz1/coap-abc/abc-device/publishEvent?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJhaXPocmlzIiwiaXNzJjoiYXV0aDAiLCJleHTiOjE2MDk0Nzc1NTUsImlhdCI6MTYwOTQ2Njc1MX2.RBs-SSa8x9VpyvBRw_EA2CUihgle5yGDJa8f2DUoGXe8d1Vah6bABILZuuyFQXcEg0Mh1BLn1p6qmbwb8BnsNg";
ssize_t proxy_uri_len = strlen(proxy_uri);
err = coap_packet_append_option(&request, COAP_OPTION_PROXY_URI, proxy_uri, proxy_uri_len);
if (err < 0) {
    LOG_DBG("Failed to create CoAP request, %d", err);
    return err;
}

...and when I inspect the CoAP message using Wireshark, the Proxy-URI option has the warning: Expert Info (Warning/Malformed): option longer than the package ...当我使用 Wireshark 检查 CoAP 消息时,Proxy-URI 选项有警告:专家信息(警告/格式错误):选项比 package

I tried setting the additional Zephyr CoAP config as follows我尝试如下设置附加的 Zephyr CoAP 配置

CONFIG_COAP_EXTENDED_OPTIONS_LEN=y
CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=800

...but had no luck. ...但没有运气。

Would anyone know what I could be missing?有人知道我可能会错过什么吗? Is there some CoAP config whose default value I need to override so as to accommodate longer Proxy-URI options?是否有一些 CoAP 配置我需要覆盖其默认值以适应更长的代理 URI 选项?

Thanks.谢谢。

The limit 268/269 is the threshold, where the option length is encoded with 1/2 bytes.限制 268/269 是阈值,其中选项长度用 1/2 字节编码。 Maybe, it's just a bug with such "large options" in the library used there.也许,这只是那里使用的库中具有如此“大选项”的错误。

Just as experiment (it doesn't work finally with the proxy you used in that tutorial), try to use instead of the "huge" COAP_OPTION_PROXY_URI a combination of COAP_OPTION_PROXY_SCHEME (http) and split the rest of the url into COAP_OPTION_URI_HOST, COAP_OPTION_URI_PATH, COAP_OPTION_URI_QUERY. Just as experiment (it doesn't work finally with the proxy you used in that tutorial), try to use instead of the "huge" COAP_OPTION_PROXY_URI a combination of COAP_OPTION_PROXY_SCHEME (http) and split the rest of the url into COAP_OPTION_URI_HOST, COAP_OPTION_URI_PATH, COAP_OPTION_URI_QUERY . That should result then smaller options than 269 (hopefully).这应该会导致比 269 更小的选项(希望如此)。 With that, check, what wireshark displays.有了它,检查一下wireshark显示的内容。 If wireshark is OK, add that hint with the option length to the question in the nordic forum.如果wireshark 没问题,请在北欧论坛的问题中添加带有选项长度的提示。 If you still don't get an answer there, please open an issue in Eclipse/Californium and I will see, what will be required for the current proxy2 implementation to work for that cloud API of that tutorial.如果您仍然没有在那里得到答案,请在 Eclipse/Californium 中打开一个问题,我会看到,当前的 proxy2 实现需要什么才能适用于该教程的云 API。

(Note: the URI "http://127.0.0.1:3000/abc/europe-xyz1/coap-abc/abc-device/publishEvent?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJhaXPocmlzIiwiaXNzJjoiYXV0aDAiLCJleHTiOjE2MDk0Nzc1NTUsImlhdCI6MTYwOTQ2Njc1MX2.RBs-SSa8x9VpyvBRw_EA2CUihgle5yGDJa8f2DUoGXe8d1Vah6bABILZuuyFQXcEg0Mh1BLn1p6qmbwb8BnsNg" will then be: (Note: the URI "http://127.0.0.1:3000/abc/europe-xyz1/coap-abc/abc-device/publishEvent?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJhaXPocmlzIiwiaXNzJjoiYXV0aDAiLCJleHTiOjE2MDk0Nzc1NTUsImlhdCI6MTYwOTQ2Njc1MX2.RBs-SSa8x9VpyvBRw_EA2CUihgle5yGDJa8f2DUoGXe8d1Vah6bABILZuuyFQXcEg0Mh1BLn1p6qmbwb8BnsNg" will then be:

COAP_OPTION_PROXY_SCHEME=http
COAP_OPTION_URI_HOST=127.0.0.1
COAP_OPTION_URI_PORT=3000
COAP_OPTION_URI_PATH=abc
COAP_OPTION_URI_PATH=europe-xyz1
COAP_OPTION_URI_PATH=coap-abc
COAP_OPTION_URI_PATH=abc-device
COAP_OPTION_URI_PATH=publishEvent
COAP_OPTION_URI_QUERY=jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJhaXPocmlzIiwiaXNzJjoiYXV0aDAiLCJleHTiOjE2MDk0Nzc1NTUsImlhdCI6MTYwOTQ2Njc1MX2.RBs-SSa8x9VpyvBRw_EA2CUihgle5yGDJa8f2DUoGXe8d1Vah6bABILZuuyFQXcEg0Mh1BLn1p6qmbwb8BnsNg

) )

Got it.知道了。 Version 1.4,1.版本 1.4,1。 coap,c, line 221. uses "delta_size" instead of "len_size". coap,c,第 221 行。使用“delta_size”而不是“len_size”。

if (len_size == 1U) {
    res = append_u8(cpkt, (uint8_t)len_ext);
    if (!res) {
        return -EINVAL;
    }
} else if (delta_size == 2U) {
    res = append_be16(cpkt, len_ext);
    if (!res) {
        return -EINVAL;
    }
}

I add this to your question in the forum.我将此添加到您在论坛中的问题中。

And https://github.com/zephyrproject-rtos/zephyr/issues/31206https://github.com/zephyrproject-rtos/zephyr/issues/31206

CoAP messages are typically limited by the application's buffer in size, and practically limited to one MTU (as IP fragmentation is rarely used together with CoAP). CoAP 消息通常受应用程序缓冲区大小的限制,实际上限制为一个 MTU(因为 IP 碎片很少与 CoAP 一起使用)。 Unlike the message's payload, an option can not be split across multiple messages using block-wise transfer.与消息的有效负载不同,一个选项不能使用分块传输拆分到多个消息中。 On the Zephyr side, the error went unnoticed because you discarded the coap_packet_append_option result code.在 Zephyr 方面,由于您丢弃了 coap_packet_append_option 结果代码,因此没有注意到该错误。

For the concrete case of this URI, you can work around the limitation using a larger message buffer (how that is done depends on how you initialized request in the first place).对于此 URI 的具体情况,您可以使用更大的消息缓冲区来解决限制(如何完成取决于您首先如何初始化request )。


Note that transporting a JWT in the URI for authentication purposes is not how authentication is typically done in CoAP applications.请注意,出于身份验证目的在 URI 中传输 JWT 并不是 CoAP 应用程序中通常进行身份验证的方式。 If your HTTP server accepts TLS client certificates instead of CWTs, you may consider provisioning the proxy with a suitable client certificate (to be used when the CoAP client is authenticated properly, eg. using DTLS or OSCORE), and then use only the almost reasonably sized token-less path.如果您的 HTTP 服务器接受 TLS 客户端证书而不是 CWT,您可以考虑为代理提供合适的客户端证书(在正确验证 CoAP 客户端时使用,例如使用 DTLS 或 OSCORE),然后仅使用几乎合理的大小的无令牌路径。


[edit after question clarification] [问题澄清后编辑]

The lack of errors indicates a flaw in the Zephyr code, either Zephyr itself or the concrete network interface used (which should not silently truncate outgoing messages without letting the OS know), and would best be addressed inside the Zephyr issue tracker.没有错误表明 Zephyr 代码存在缺陷,无论是 Zephyr 本身还是使用的具体网络接口(不应在不让操作系统知道的情况下静默截断传出消息),最好在 Zephyr 问题跟踪器中解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM