From aa2f97c80ffeca7d65c9af77b657c1122839f9f8 Mon Sep 17 00:00:00 2001
From: Ken Bannister <kb2ma@runbox.com>
Date: Sun, 18 Jun 2017 06:29:43 -0400
Subject: [PATCH] net/gcoap: Protect update to open requests with mutex.

---
 sys/include/net/gcoap.h                | 2 ++
 sys/net/application_layer/coap/gcoap.c | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/sys/include/net/gcoap.h b/sys/include/net/gcoap.h
index df3045798f..47c25c65fd 100644
--- a/sys/include/net/gcoap.h
+++ b/sys/include/net/gcoap.h
@@ -212,6 +212,7 @@
 #include <stdint.h>
 #include <stdatomic.h>
 #include "net/sock/udp.h"
+#include "mutex.h"
 #include "nanocoap.h"
 #include "xtimer.h"
 
@@ -439,6 +440,7 @@ typedef struct {
  * @brief   Container for the state of gcoap itself
  */
 typedef struct {
+    mutex_t lock;                       /**< Shares state attributes safely */
     gcoap_listener_t *listeners;        /**< List of registered listeners */
     gcoap_request_memo_t open_reqs[GCOAP_REQ_WAITING_MAX];
                                         /**< Storage for open requests; if first
diff --git a/sys/net/application_layer/coap/gcoap.c b/sys/net/application_layer/coap/gcoap.c
index e615af2ecd..0bfb0c376b 100644
--- a/sys/net/application_layer/coap/gcoap.c
+++ b/sys/net/application_layer/coap/gcoap.c
@@ -585,6 +585,7 @@ kernel_pid_t gcoap_init(void)
     _pid = thread_create(_msg_stack, sizeof(_msg_stack), THREAD_PRIORITY_MAIN - 1,
                             THREAD_CREATE_STACKTEST, _event_loop, NULL, "coap");
 
+    mutex_init(&_coap_state.lock);
     /* Blank lists so we know if an entry is available. */
     memset(&_coap_state.open_reqs[0], 0, sizeof(_coap_state.open_reqs));
     memset(&_coap_state.observers[0], 0, sizeof(_coap_state.observers));
@@ -683,6 +684,7 @@ size_t gcoap_req_send2(const uint8_t *buf, size_t len,
     assert(resp_handler != NULL);
 
     /* Find empty slot in list of open requests. */
+    mutex_lock(&_coap_state.lock);
     for (int i = 0; i < GCOAP_REQ_WAITING_MAX; i++) {
         if (_coap_state.open_reqs[i].state == GCOAP_MEMO_UNUSED) {
             memo = &_coap_state.open_reqs[i];
@@ -690,6 +692,8 @@ size_t gcoap_req_send2(const uint8_t *buf, size_t len,
             break;
         }
     }
+    mutex_unlock(&_coap_state.lock);
+
     if (memo) {
         memcpy(&memo->hdr_buf[0], buf, GCOAP_HEADER_MAXLEN);
         memo->resp_handler = resp_handler;
-- 
GitLab