Michael-7
Michael-7

Reputation: 1789

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

I am developing a CoAP client on the nRF9160 DK, running Zephyr RTOS. I am having trouble with longer Proxy-URI's; short URIs (268 characters and below) work fine and the coap message reaches the server as expected. However, messages with longer Proxy-URIs (269 characters and above) fail to go through for some reason. 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.

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

I tried setting the additional Zephyr CoAP config as follows

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?

Thanks.

Upvotes: 0

Views: 627

Answers (3)

Achim Kraus
Achim Kraus

Reputation: 824

Got it! Version 1.4.1, coap.c, line 221, uses "delta_size" instead of "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/31206

Upvotes: 2

Achim Kraus
Achim Kraus

Reputation: 824

The limit 268/269 is the threshold, where the option length is encoded with 1/2 bytes. 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. That should result then smaller options than 269 (hopefully). With that, check, what wireshark displays. If wireshark is OK, add that hint with the option length to the question in the nordic forum. 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.

(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

)

Upvotes: 2

chrysn
chrysn

Reputation: 928

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). 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.

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).


Note that transporting a JWT in the URI for authentication purposes is not how authentication is typically done in CoAP applications. 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.


[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.

Upvotes: 0

Related Questions