Skip to content

coap_session.c: Fix token generation when no token is provided#1904

Open
dsch wants to merge 1 commit intoobgm:developfrom
dsch:observe-start-token
Open

coap_session.c: Fix token generation when no token is provided#1904
dsch wants to merge 1 commit intoobgm:developfrom
dsch:observe-start-token

Conversation

@dsch
Copy link

@dsch dsch commented Mar 4, 2026

When coap_session_t::tx_token is initialized to zero, the resulting request token has zero length. Some request types, such as Observe, require a non‑empty token. Avoiding initializing tx_token to -1 prevents generation of empty tokens and restores the behavior from before commits #1276 and #1329, while still ensuring that user‑provided tokens are no longer incremented before transmission.

@mrdeep1
Copy link
Collaborator

mrdeep1 commented Mar 4, 2026

There currently is an issue with CIFuzz which I am looking at.

@mrdeep1
Copy link
Collaborator

mrdeep1 commented Mar 4, 2026

Some request types, such as Observe, require a non‑empty token.

It is not a requirement per-se, but if multiple Observe requests are going to be initiated (and are concurrent), then different tokens must be in use so that the client can differentiate between the unsolicited responses. An empty Token is a valid alternative to a non-empty Token.

With the examples coap-client, if no token is specified (with the -T option), then the libcoap logic needs to send an empty token, not a token with a value of 1.

coap_session_init_token(3) is available to seed the token value.

Is this because a server you are using cannot handle an empty Token for an Observe request?

[This PR will need to be rebased with the latest develop branch to fix the CIFuzz CI failure.]

When `coap_session_t::tx_token` is initialized to zero, the resulting request
token has zero length. Some request types, such as Observe, require a non‑empty
token. Avoiding initializing `tx_token` to -1 prevents generation of empty tokens
and restores the behavior from before commits obgm#1276 and obgm#1329, while still ensuring
that user‑provided tokens are no longer incremented before transmission.
@dsch dsch force-pushed the observe-start-token branch from 42cabce to 30ab581 Compare March 5, 2026 07:57
@dsch
Copy link
Author

dsch commented Mar 5, 2026

Thank you for the detailed explanation.

Is this because a server you are using cannot handle an empty Token for an Observe request?

Indeed, we are use Zephyr's CoAP server implementation which rejects Observe requests without Token.
https://github.com/zephyrproject-rtos/zephyr/blob/1f672c777a05d11adbd1dda9bdc0af530799c7d8/subsys/net/lib/coap/coap_server.c#L681-L684

My first thought was that if the behavior of coap-client changed since 4.3.4 the easiest way to restore functionality would be to patch libcoap. But as you pointed out an empty Token is valid also for Observe requests the better solution would be to fix this in the Zephyr implementation.

What do you think of adding a default token to coap-client Observe requests as it's rather unusual to register an observer without token?

Example

diff --git a/examples/coap-client.c b/examples/coap-client.c
index 7cae13dc..931cda49 100644
--- a/examples/coap-client.c
+++ b/examples/coap-client.c
@@ -1124,22 +1124,24 @@
 static void
 cmdline_subscribe(char *arg) {
   uint8_t buf[4];
 
   obs_seconds = atoi(arg);
   coap_insert_optlist(&optlist,
                       coap_new_optlist(COAP_OPTION_OBSERVE,
                                        coap_encode_var_safe(buf, sizeof(buf),
                                                             COAP_OBSERVE_ESTABLISH), buf)
                      );
   doing_observe = 1;
+  the_token.length = 1;
+  the_token.s[0] = 0x01; /* random token */
 }

@mrdeep1
Copy link
Collaborator

mrdeep1 commented Mar 5, 2026

Actually, it is https://github.com/zephyrproject-rtos/zephyr/blob/1f672c777a05d11adbd1dda9bdc0af530799c7d8/subsys/net/lib/coap/coap_server.c#L698-701 where a zero length token is rejected. Lots of the following code / functions can't handle / reject a zero length token.

What do you think of adding a default token to coap-client Observe requests

Certainly a work around. However, if the -T option is defined before the -s option on the coap-client invocation, your suggested code change overwrites the specified token. The documentation would need to be updated that a (if not specified otherwise) default token is configured.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants