From df90dfd7b1ab69661d09b1da713ba4bcddbd7a47 Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Mon, 11 May 2026 15:44:21 +0100 Subject: [PATCH] coap_subscribe.c: Sanity check persist startup logic --- include/coap3/coap_resource_internal.h | 11 +++++++++ src/coap_net.c | 20 ++-------------- src/coap_resource.c | 33 +++++++++++++++++++++++++- src/coap_subscribe.c | 17 +++++-------- 4 files changed, 51 insertions(+), 30 deletions(-) diff --git a/include/coap3/coap_resource_internal.h b/include/coap3/coap_resource_internal.h index 5d107a07..b094afda 100644 --- a/include/coap3/coap_resource_internal.h +++ b/include/coap3/coap_resource_internal.h @@ -253,6 +253,17 @@ coap_print_status_t coap_print_wellknown_lkd(coap_context_t *context, size_t offset, const coap_string_t *query_filter); +/** + * Check to see if a dynamic resource needs to be added. + * + * @param session Session potentiall adding a new dynamic resource. + * @param pdu PDU that is asking for an unknown resource. + * + * @return Created resource or NULL is resource eneration not applicable. + */ +coap_resource_t *coap_add_dynamic_resource(coap_session_t *session, + coap_pdu_t *pdu); + /** @} */ #endif /* COAP_SERVER_SUPPORT */ diff --git a/src/coap_net.c b/src/coap_net.c index 8396396a..d26630a9 100644 --- a/src/coap_net.c +++ b/src/coap_net.c @@ -3870,28 +3870,12 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu uri_path->s); resp = 202; goto fail_response; - } else if ((context->dyn_create_handler != NULL) && - (pdu->code == COAP_REQUEST_CODE_PUT || pdu->code == COAP_REQUEST_CODE_POST)) { - /* Above test must be the same as in coap_op_dyn_resource_load_disk() */ - if (context->dynamic_cur < context->dynamic_max || context->dynamic_max == 0) { -#if COAP_WITH_OBSERVE_PERSIST - /* If we are maintaining Observe persist */ - context->unknown_pdu = pdu; - context->unknown_session = session; -#endif /* COAP_WITH_OBSERVE_PERSIST */ - coap_lock_callback_ret(resource, context->dyn_create_handler(session, pdu)); -#if COAP_WITH_OBSERVE_PERSIST - /* If we are maintaining Observe persist */ - context->unknown_pdu = NULL; - context->unknown_session = NULL; -#endif /* COAP_WITH_OBSERVE_PERSIST */ - } + } else if (context->dyn_create_handler != NULL) { + resource = coap_add_dynamic_resource(session, pdu); if (!resource) { resp = 406; goto fail_response; } - context->dynamic_cur++; - resource->is_dynamic = 1; } else { /* request for any another resource, return 4.04 */ coap_log_debug("request for unknown resource '%*.*s', return 4.04\n", diff --git a/src/coap_resource.c b/src/coap_resource.c index 093cc0bc..f154b1cc 100644 --- a/src/coap_resource.c +++ b/src/coap_resource.c @@ -1572,4 +1572,35 @@ void coap_resource_reference_lkd(coap_resource_t *resource) { resource->ref++; } -#endif /* ! COAP_SERVER_SUPPORT */ + +coap_resource_t * +coap_add_dynamic_resource(coap_session_t *session, coap_pdu_t *pdu) { + coap_context_t *context = session->context; + coap_resource_t *resource; + + if ((context->dyn_create_handler != NULL) && + (pdu->code == COAP_REQUEST_CODE_PUT || pdu->code == COAP_REQUEST_CODE_POST)) { + /* Above test must be the same as in coap_op_dyn_resource_load_disk() */ + if (context->dynamic_cur < context->dynamic_max || context->dynamic_max == 0) { +#if COAP_WITH_OBSERVE_PERSIST + /* If we are maintaining Observe persist */ + context->unknown_pdu = pdu; + context->unknown_session = session; +#endif /* COAP_WITH_OBSERVE_PERSIST */ + coap_lock_callback_ret(resource, context->dyn_create_handler(session, pdu)); +#if COAP_WITH_OBSERVE_PERSIST + /* If we are maintaining Observe persist */ + context->unknown_pdu = NULL; + context->unknown_session = NULL; +#endif /* COAP_WITH_OBSERVE_PERSIST */ + if (resource) { + context->dynamic_cur++; + resource->is_dynamic = 1; + } + return resource; + } + } + return NULL; +} + +#endif /* COAP_SERVER_SUPPORT */ diff --git a/src/coap_subscribe.c b/src/coap_subscribe.c index b5b7774e..33483dc7 100644 --- a/src/coap_subscribe.c +++ b/src/coap_subscribe.c @@ -979,17 +979,12 @@ coap_op_dyn_resource_load_disk(coap_context_t *ctx) { raw_packet->length, request)) { goto fail; } - r = ctx->unknown_resource; - if ((ctx->dyn_create_handler != NULL) && - (request->code == COAP_REQUEST_CODE_PUT || request->code == COAP_REQUEST_CODE_POST)) { - /* Above test must be the same as in handle_request() */ - if (ctx->dynamic_cur < ctx->dynamic_max || ctx->dynamic_max == 0) { - ctx->unknown_pdu = request; - ctx->unknown_session = session; - coap_lock_callback_ret(r, ctx->dyn_create_handler(session, request)); - ctx->unknown_pdu = NULL; - ctx->unknown_session = NULL; - } + if (!COAP_PDU_IS_REQUEST(request)) { + goto next; + } + r = coap_add_dynamic_resource(session, request); + if (!r) { + r = ctx->unknown_resource; } if (!r || !r->handler[request->code-1]) goto next;