Skip to content

Commit

Permalink
coap_delete_pdu: Add in multi-threaded lock protection
Browse files Browse the repository at this point in the history
The reference counter needs to be protected.
  • Loading branch information
mrdeep1 committed Jan 28, 2025
1 parent 109842b commit 6701466
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 71 deletions.
13 changes: 9 additions & 4 deletions include/coap3/coap_pdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,14 +400,19 @@ COAP_API coap_pdu_t *coap_new_pdu(coap_pdu_type_t type, coap_pdu_code_t code,
coap_session_t *session);

/**
* Dispose of an CoAP PDU and frees associated storage.
* Not that in general you should not call this function directly.
* Dispose of an CoAP PDU and free off associated storage.
*
* Note: In general you should not call this function directly.
* When a PDU is sent with coap_send(), coap_delete_pdu() will be called
* automatically for you.
* automatically for you. This is not for the case for coap_send_recv()
* where the sending and receiving PDUs need to be explicitly deleted.
*
* Note: If called with a reference count > 0, the reference count is
* decremented and the PDU still exists.
*
* @param pdu The PDU for free off.
*/
void coap_delete_pdu(coap_pdu_t *pdu);
COAP_API void coap_delete_pdu(coap_pdu_t *pdu);

/**
* Duplicate an existing PDU. Specific options can be ignored and not copied
Expand Down
17 changes: 17 additions & 0 deletions include/coap3/coap_pdu_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,23 @@ int coap_option_check_repeatable(coap_option_num_t number);
coap_pdu_t *coap_new_pdu_lkd(coap_pdu_type_t type, coap_pdu_code_t code,
coap_session_t *session);

/**
* Dispose of an CoAP PDU and free off associated storage.
*
* Note: This function must be called in the locked state.
*
* Note: In general you should not call this function directly.
* When a PDU is sent with coap_send(), coap_delete_pdu() will be called
* automatically for you. This is not for the case for coap_send_recv()
* where the sending and receiving PDUs need to be explicitly deleted.
*
* Note: If called with a reference count > 0, the reference count is
* decremented and the PDU still exists.
*
* @param pdu The PDU for free off.
*/
void coap_delete_pdu_lkd(coap_pdu_t *pdu);

/**
* Duplicate an existing PDU. Specific options can be ignored and not copied
* across. The PDU data payload is not copied across.
Expand Down
1 change: 0 additions & 1 deletion include/coap3/coap_threadsafe_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,6 @@ int coap_lock_lock_func(void);
* @param c Context.
*/
#define coap_lock_unlock(c) do { \
assert(c); \
coap_lock_unlock_func(); \
} while (0)

Expand Down
2 changes: 1 addition & 1 deletion src/coap_async.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ coap_free_async_sub(coap_context_t *context, coap_async_t *s) {
coap_session_release_lkd(s->session);
}
if (s->pdu) {
coap_delete_pdu(s->pdu);
coap_delete_pdu_lkd(s->pdu);
s->pdu = NULL;
}
coap_free_type(COAP_STRING, s);
Expand Down
12 changes: 6 additions & 6 deletions src/coap_block.c
Original file line number Diff line number Diff line change
Expand Up @@ -1930,7 +1930,7 @@ coap_send_q_blocks(coap_session_t *session,
if (send_pdu == COAP_SEND_INC_PDU &&
(mid = coap_send_internal(session, pdu)) == COAP_INVALID_MID) {
/* Not expected, underlying issue somewhere */
coap_delete_pdu(block_pdu);
coap_delete_pdu_lkd(block_pdu);
return COAP_INVALID_MID;
}

Expand Down Expand Up @@ -1973,8 +1973,8 @@ coap_send_q_blocks(coap_session_t *session,
block.szx),
buf)) {
coap_log_warn("Internal update issue option\n");
coap_delete_pdu(block_pdu);
coap_delete_pdu(t_pdu);
coap_delete_pdu_lkd(block_pdu);
coap_delete_pdu_lkd(t_pdu);
break;
}

Expand All @@ -1984,8 +1984,8 @@ coap_send_q_blocks(coap_session_t *session,
block.num,
block.szx)) {
coap_log_warn("Internal update issue data\n");
coap_delete_pdu(block_pdu);
coap_delete_pdu(t_pdu);
coap_delete_pdu_lkd(block_pdu);
coap_delete_pdu_lkd(t_pdu);
break;
}
if (COAP_PDU_IS_RESPONSE(block_pdu)) {
Expand All @@ -1994,7 +1994,7 @@ coap_send_q_blocks(coap_session_t *session,
mid = coap_send_internal(session, block_pdu);
if (mid == COAP_INVALID_MID) {
/* Not expected, underlying issue somewhere */
coap_delete_pdu(t_pdu);
coap_delete_pdu_lkd(t_pdu);
return COAP_INVALID_MID;
}
block_pdu = t_pdu;
Expand Down
4 changes: 2 additions & 2 deletions src/coap_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ coap_new_cache_entry_lkd(coap_session_t *session, const coap_pdu_t *pdu,
entry->pdu = coap_pdu_init(pdu->type, pdu->code, pdu->mid, pdu->alloc_size);
if (entry->pdu) {
if (!coap_pdu_resize(entry->pdu, pdu->alloc_size)) {
coap_delete_pdu(entry->pdu);
coap_delete_pdu_lkd(entry->pdu);
coap_free_type(COAP_CACHE_ENTRY, entry);
return NULL;
}
Expand Down Expand Up @@ -288,7 +288,7 @@ coap_delete_cache_entry(coap_context_t *ctx, coap_cache_entry_t *cache_entry) {
HASH_DELETE(hh, ctx->cache, cache_entry);
}
if (cache_entry->pdu) {
coap_delete_pdu(cache_entry->pdu);
coap_delete_pdu_lkd(cache_entry->pdu);
}
coap_delete_cache_key(cache_entry->cache_key);
if (cache_entry->callback && cache_entry->app_data) {
Expand Down
8 changes: 4 additions & 4 deletions src/coap_io_lwip.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ coap_recvc(void *arg, struct udp_pcb *upcb, struct pbuf *p,
#if NO_SYS == 0
sys_sem_signal(&coap_io_timeout_sem);
#endif /* NO_SYS == 0 */
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return;

error:
Expand All @@ -219,7 +219,7 @@ coap_recvc(void *arg, struct udp_pcb *upcb, struct pbuf *p,
*/
if (session)
coap_send_rst_lkd(session, pdu);
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return;
}
#endif /* ! COAP_CLIENT_SUPPORT */
Expand Down Expand Up @@ -299,7 +299,7 @@ coap_udp_recvs(void *arg, struct udp_pcb *upcb, struct pbuf *p,
coap_dispatch(ep->context, session, pdu);
}

coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
coap_free_packet(packet);
coap_lock_unlock(ep->context);
#if NO_SYS == 0
Expand All @@ -317,7 +317,7 @@ coap_udp_recvs(void *arg, struct udp_pcb *upcb, struct pbuf *p,
*/
if (session && pdu)
coap_send_rst_lkd(session, pdu);
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
coap_free_packet(packet);
coap_lock_unlock(ep->context);
return;
Expand Down
42 changes: 21 additions & 21 deletions src/coap_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ coap_delete_node_lkd(coap_queue_t *node) {
if (!node)
return 0;

coap_delete_pdu(node->pdu);
coap_delete_pdu_lkd(node->pdu);
if (node->session) {
/*
* Need to remove out of context->sendqueue as added in by coap_wait_ack()
Expand Down Expand Up @@ -1203,7 +1203,7 @@ coap_send_test_extended_token(coap_session_t *session) {

token = coap_new_binary(session->max_token_size);
if (token == NULL) {
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return COAP_INVALID_MID;
}
for (i = 0; i < session->max_token_size; i++) {
Expand Down Expand Up @@ -1495,7 +1495,7 @@ coap_send_lkd(coap_session_t *session, coap_pdu_t *pdu) {
ret = coap_cancel_observe_lkd(session, &tmp, pdu->type);
if (ret == 1) {
/* Observe Cancel successfully sent */
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return ret;
}
/* Some mismatch somewhere - continue to send original packet */
Expand Down Expand Up @@ -1671,7 +1671,7 @@ coap_send_lkd(coap_session_t *session, coap_pdu_t *pdu) {
return mid;

error:
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return COAP_INVALID_MID;
}

Expand Down Expand Up @@ -1725,13 +1725,13 @@ coap_send_internal(coap_session_t *session, coap_pdu_t *pdu) {
if (hop_limit == 1) {
coap_log_warn("Proxy loop detected '%s'\n",
(char *)pdu->data);
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return (coap_mid_t)COAP_DROPPED_RESPONSE;
} else if (hop_limit < 1 || hop_limit > 255) {
/* Something is bad - need to drop this pdu (TODO or delete option) */
coap_log_warn("Proxy return has bad hop limit count '%zu'\n",
hop_limit);
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return (coap_mid_t)COAP_DROPPED_RESPONSE;
}
hop_limit--;
Expand Down Expand Up @@ -1761,7 +1761,7 @@ coap_send_internal(coap_session_t *session, coap_pdu_t *pdu) {
a_match[len] == ' ')) {
coap_log_warn("Proxy loop detected '%s'\n",
(char *)pdu->data);
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return (coap_mid_t)COAP_DROPPED_RESPONSE;
}
}
Expand Down Expand Up @@ -1856,7 +1856,7 @@ coap_send_internal(coap_session_t *session, coap_pdu_t *pdu) {
goto error;
}
bytes_written = coap_send_pdu(session, osc_pdu, NULL);
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
pdu = osc_pdu;
} else
#endif /* COAP_OSCORE_SUPPORT */
Expand Down Expand Up @@ -1886,7 +1886,7 @@ coap_send_internal(coap_session_t *session, coap_pdu_t *pdu) {
if (pdu->type != COAP_MESSAGE_CON
|| COAP_PROTO_RELIABLE(session->proto)) {
coap_mid_t id = pdu->mid;
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return id;
}

Expand All @@ -1903,7 +1903,7 @@ coap_send_internal(coap_session_t *session, coap_pdu_t *pdu) {
node->timeout = coap_calc_timeout(session, r);
return coap_wait_ack(session->context, session, node);
error:
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return COAP_INVALID_MID;
}

Expand Down Expand Up @@ -2033,7 +2033,7 @@ coap_send_recv_lkd(coap_session_t *session, coap_pdu_t *request_pdu,
session->doing_send_recv = 0;
if (session->resp_pdu && session->resp_pdu->ref)
session->resp_pdu->ref--;
coap_delete_pdu(session->resp_pdu);
coap_delete_pdu_lkd(session->resp_pdu);
session->resp_pdu = NULL;
coap_delete_bin_const(session->req_token);
session->req_token = NULL;
Expand Down Expand Up @@ -2278,12 +2278,12 @@ coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now)
if (!coap_pdu_parse(session->proto, packet->payload, bytes_read, pdu)) {
coap_handle_event_lkd(session->context, COAP_EVENT_BAD_PACKET, session);
coap_log_warn("discard malformed PDU\n");
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return;
}

coap_dispatch(ctx, session, pdu);
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return;
}
} else {
Expand Down Expand Up @@ -2315,7 +2315,7 @@ coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now)
&& coap_pdu_parse_opt(session->partial_pdu)) {
coap_dispatch(ctx, session, session->partial_pdu);
}
coap_delete_pdu(session->partial_pdu);
coap_delete_pdu_lkd(session->partial_pdu);
session->partial_pdu = NULL;
session->partial_read = 0;
} else {
Expand Down Expand Up @@ -2362,7 +2362,7 @@ coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now)
if (coap_pdu_parse_header(session->partial_pdu, session->proto)) {
coap_dispatch(ctx, session, session->partial_pdu);
}
coap_delete_pdu(session->partial_pdu);
coap_delete_pdu_lkd(session->partial_pdu);
session->partial_pdu = NULL;
session->partial_read = 0;
}
Expand Down Expand Up @@ -2661,7 +2661,7 @@ coap_handle_dgram(coap_context_t *ctx, coap_session_t *session,
}

coap_dispatch(ctx, session, pdu);
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return 0;

error:
Expand All @@ -2670,7 +2670,7 @@ coap_handle_dgram(coap_context_t *ctx, coap_session_t *session,
* https://rfc-editor.org/rfc/rfc7252#section-4.3 MAY send RST
*/
coap_send_rst_lkd(session, pdu);
coap_delete_pdu(pdu);
coap_delete_pdu_lkd(pdu);
return -1;
}

Expand Down Expand Up @@ -2878,7 +2878,7 @@ coap_new_error_response(const coap_pdu_t *request, coap_pdu_code_t code,
if (!coap_add_token(response, request->actual_token.length,
request->actual_token.s)) {
coap_log_debug("cannot add token to error response\n");
coap_delete_pdu(response);
coap_delete_pdu_lkd(response);
return NULL;
}

Expand Down Expand Up @@ -3754,7 +3754,7 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu
response->mid);
coap_show_pdu(COAP_LOG_DEBUG, response);
drop_it_no_debug:
coap_delete_pdu(response);
coap_delete_pdu_lkd(response);
}
if (query)
coap_delete_string(query);
Expand All @@ -3781,7 +3781,7 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu
return;

fail_response:
coap_delete_pdu(response);
coap_delete_pdu_lkd(response);
response =
coap_new_error_response(pdu, COAP_RESPONSE_CODE(resp),
&opt_filter);
Expand Down Expand Up @@ -4414,7 +4414,7 @@ coap_dispatch(coap_context_t *context, coap_session_t *session,
}
coap_delete_node_lkd(sent);
#if COAP_OSCORE_SUPPORT
coap_delete_pdu(dec_pdu);
coap_delete_pdu_lkd(dec_pdu);
#endif /* COAP_OSCORE_SUPPORT */
}

Expand Down
Loading

0 comments on commit 6701466

Please sign in to comment.