From df95d5bcc3ce5a016d107d6f97aad22ba3d140f2 Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Mon, 24 Mar 2025 16:04:12 +0000 Subject: [PATCH] Proxy: Ignore idle timeout if observe subscription on session Ignore the idle_timeout_secs parameter for a server if there is one or more active observe subscriptions for the server session. --- include/coap3/coap_proxy.h | 4 +++- include/coap3/coap_proxy_internal.h | 6 +++++- man/coap_proxy.txt.in | 4 +++- src/coap_proxy.c | 32 ++++++++++++++++++++++------- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/include/coap3/coap_proxy.h b/include/coap3/coap_proxy.h index 8946000a..83341003 100644 --- a/include/coap3/coap_proxy.h +++ b/include/coap3/coap_proxy.h @@ -60,7 +60,9 @@ typedef struct coap_proxy_server_list_t { server, else 0 for all clients to share the same ongoing session */ unsigned int idle_timeout_secs; /**< Proxy upstream session idle timeout - (0 is no timeout) */ + (0 is no timeout). Timeout is ignored + if there are any active upstream Observe + requests */ } coap_proxy_server_list_t; /** diff --git a/include/coap3/coap_proxy_internal.h b/include/coap3/coap_proxy_internal.h index cfc585c1..b24ccc12 100644 --- a/include/coap3/coap_proxy_internal.h +++ b/include/coap3/coap_proxy_internal.h @@ -41,8 +41,12 @@ struct coap_proxy_list_t { size_t req_count; /**< Count of incoming request info */ coap_uri_t uri; /**< URI info for connection */ uint8_t *uri_host_keep; /**< memory for uri.host */ - coap_tick_t idle_timeout_ticks; /**< Idle timeout (0 == no timeout) */ + coap_tick_t idle_timeout_ticks; /**< Idle timeout (0 == no timeout). Timeout + is ignored if there are any active + upstream Observe requests */ coap_tick_t last_used; /**< Last time entry was used */ + uint64_t res_tx_token; /**< Copy of ongoing session tx_token for restart */ + coap_lg_crcv_t *res_lg_crcv; /**< Copy of ongoing session lg_crcv for restart */ }; /** diff --git a/man/coap_proxy.txt.in b/man/coap_proxy.txt.in index 9c6bbcea..b5f06750 100644 --- a/man/coap_proxy.txt.in +++ b/man/coap_proxy.txt.in @@ -137,7 +137,9 @@ typedef struct coap_proxy_server_list_t { server, else 0 for all clients to share the same ongoing session */ unsigned int idle_timeout_secs; /* Proxy upstream session idle timeout - (0 is no timeout) */ + (0 is no timeout). Timeout is ignored + if there are any active upstream Observe + requests */ } coap_proxy_server_list_t; ---- diff --git a/src/coap_proxy.c b/src/coap_proxy.c index 4a61e551..f031029d 100644 --- a/src/coap_proxy.c +++ b/src/coap_proxy.c @@ -51,6 +51,21 @@ coap_proxy_cleanup(coap_context_t *context) { coap_free_type(COAP_STRING, context->proxy_list); } +static int +coap_proxy_check_observe(coap_proxy_list_t *proxy_entry) { + if (proxy_entry && proxy_entry->ongoing) { + /* Need to see if there are any Observes active */ + coap_lg_crcv_t *lg_crcv; + + LL_FOREACH(proxy_entry->ongoing->lg_crcv, lg_crcv) { + if (lg_crcv->observe_set) { + return 1; + } + } + } + return 0; +} + /* * return 1 if there is a future expire time, else 0. * update tim_rem with remaining value if return is 1. @@ -63,16 +78,19 @@ coap_proxy_check_timeouts(coap_context_t *context, coap_tick_t now, *tim_rem = -1; for (i = 0; i < context->proxy_list_count; i++) { - coap_proxy_list_t *proxy_list = &context->proxy_list[i]; + coap_proxy_list_t *proxy_entry = &context->proxy_list[i]; - if (proxy_list->ongoing && proxy_list->idle_timeout_ticks) { - if (proxy_list->last_used + proxy_list->idle_timeout_ticks <= now) { + if (coap_proxy_check_observe(proxy_entry)) + continue; + + if (proxy_entry->ongoing && proxy_entry->idle_timeout_ticks) { + if (proxy_entry->last_used + proxy_entry->idle_timeout_ticks <= now) { /* Drop session to upstream server */ - coap_session_release_lkd(proxy_list->ongoing); - proxy_list->ongoing = NULL; + coap_session_release_lkd(proxy_entry->ongoing); + proxy_entry->ongoing = NULL; } else { - if (*tim_rem > proxy_list->last_used + proxy_list->idle_timeout_ticks - now) { - *tim_rem = proxy_list->last_used + proxy_list->idle_timeout_ticks - now; + if (*tim_rem > proxy_entry->last_used + proxy_entry->idle_timeout_ticks - now) { + *tim_rem = proxy_entry->last_used + proxy_entry->idle_timeout_ticks - now; } ret = 1; }