From 24b21dbfbc898573c3743f38ea63d1fb8adf6c76 Mon Sep 17 00:00:00 2001 From: Ken Bannister <kb2ma@runbox.com> Date: Sun, 18 Jun 2017 06:16:15 -0400 Subject: [PATCH] net/gcoap: Protect message ID state with atomic updates. Also changed semantics for storage of message ID, from last ID to next ID. This change provides idiomatic use of the return value of the atomic function, without other side effects on gcoap. --- sys/include/net/gcoap.h | 4 +++- sys/net/application_layer/coap/gcoap.c | 23 ++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/sys/include/net/gcoap.h b/sys/include/net/gcoap.h index ebac4e16d4..df3045798f 100644 --- a/sys/include/net/gcoap.h +++ b/sys/include/net/gcoap.h @@ -209,6 +209,8 @@ #ifndef NET_GCOAP_H #define NET_GCOAP_H +#include <stdint.h> +#include <stdatomic.h> #include "net/sock/udp.h" #include "nanocoap.h" #include "xtimer.h" @@ -442,7 +444,7 @@ typedef struct { /**< Storage for open requests; if first byte of an entry is zero, the entry is available */ - uint16_t last_message_id; /**< Last message ID used */ + atomic_uint next_message_id; /**< Next message ID to use */ sock_udp_ep_t observers[GCOAP_OBS_CLIENTS_MAX]; /**< Observe clients; allows reuse for observe memos */ diff --git a/sys/net/application_layer/coap/gcoap.c b/sys/net/application_layer/coap/gcoap.c index cd933dbe2c..e615af2ecd 100644 --- a/sys/net/application_layer/coap/gcoap.c +++ b/sys/net/application_layer/coap/gcoap.c @@ -590,7 +590,7 @@ kernel_pid_t gcoap_init(void) memset(&_coap_state.observers[0], 0, sizeof(_coap_state.observers)); memset(&_coap_state.observe_memos[0], 0, sizeof(_coap_state.observe_memos)); /* randomize initial value */ - _coap_state.last_message_id = random_uint32() & 0xFFFF; + atomic_init(&_coap_state.next_message_id, (unsigned)random_uint32()); return _pid; } @@ -609,7 +609,6 @@ void gcoap_register_listener(gcoap_listener_t *listener) int gcoap_req_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code, char *path) { - ssize_t hdrlen; (void)len; pdu->hdr = (coap_hdr_t *)buf; @@ -624,11 +623,13 @@ int gcoap_req_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code, &rand, (GCOAP_TOKENLEN - i >= 4) ? 4 : GCOAP_TOKENLEN - i); } - hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, &token[0], GCOAP_TOKENLEN, - code, ++_coap_state.last_message_id); + uint16_t msgid = (uint16_t)atomic_fetch_add(&_coap_state.next_message_id, 1); + ssize_t hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, &token[0], GCOAP_TOKENLEN, + code, msgid); #else - hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, NULL, GCOAP_TOKENLEN, - code, ++_coap_state.last_message_id); + uint16_t msgid = (uint16_t)atomic_fetch_add(&_coap_state.next_message_id, 1); + ssize_t hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, NULL, GCOAP_TOKENLEN, + code, msgid); #endif if (hdrlen > 0) { @@ -742,7 +743,6 @@ int gcoap_resp_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, unsigned code) int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, const coap_resource_t *resource) { - ssize_t hdrlen; gcoap_observe_memo_t *memo = NULL; _find_obs_memo_resource(&memo, resource); @@ -751,10 +751,11 @@ int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, return GCOAP_OBS_INIT_UNUSED; } - pdu->hdr = (coap_hdr_t *)buf; - hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, &memo->token[0], - memo->token_len, COAP_CODE_CONTENT, - ++_coap_state.last_message_id); + pdu->hdr = (coap_hdr_t *)buf; + uint16_t msgid = (uint16_t)atomic_fetch_add(&_coap_state.next_message_id, 1); + ssize_t hdrlen = coap_build_hdr(pdu->hdr, COAP_TYPE_NON, &memo->token[0], + memo->token_len, COAP_CODE_CONTENT, msgid); + if (hdrlen > 0) { uint32_t now = xtimer_now_usec(); pdu->observe_value = (now >> GCOAP_OBS_TICK_EXPONENT) & 0xFFFFFF; -- GitLab