From 2f25c950af21fcd563882f45800792cd1f8ae4bb Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Mon, 19 Sep 2022 15:19:48 +0100 Subject: [PATCH] net.c: Call nack handler for badly formatted response packet If a response packet is received that is badly formatted, invoke the nack handler (if defined) with COAP_NACK_BAD_RESPONSE so that the requestor knows there is an issue, rather than timing out. However, if the response packet is so badly formatted, or it is not possible to find the requesting packet, then this nack event will not trigger, but an event is triggered with COAP_EVENT_BAD_PACKET. --- examples/coap-client.c | 2 ++ examples/coap-server.c | 2 ++ include/coap3/coap_event.h | 8 +++++++- include/coap3/coap_io.h | 3 ++- man/coap_handler.txt.in | 5 +++++ src/net.c | 21 +++++++++++++++++++-- 6 files changed, 37 insertions(+), 4 deletions(-) diff --git a/examples/coap-client.c b/examples/coap-client.c index 82320dea..2c4be330 100644 --- a/examples/coap-client.c +++ b/examples/coap-client.c @@ -360,6 +360,7 @@ event_handler(coap_session_t *session COAP_UNUSED, case COAP_EVENT_XMIT_BLOCK_FAIL: case COAP_EVENT_SERVER_SESSION_NEW: case COAP_EVENT_SERVER_SESSION_DEL: + case COAP_EVENT_BAD_PACKET: default: break; } @@ -381,6 +382,7 @@ nack_handler(coap_session_t *session COAP_UNUSED, quit = 1; break; case COAP_NACK_ICMP_ISSUE: + case COAP_NACK_BAD_RESPONSE: default: ; } diff --git a/examples/coap-server.c b/examples/coap-server.c index 76e8941b..c13f7958 100644 --- a/examples/coap-server.c +++ b/examples/coap-server.c @@ -1645,6 +1645,7 @@ proxy_event_handler(coap_session_t *session, case COAP_EVENT_XMIT_BLOCK_FAIL: case COAP_EVENT_SERVER_SESSION_NEW: case COAP_EVENT_SERVER_SESSION_DEL: + case COAP_EVENT_BAD_PACKET: default: break; } @@ -1788,6 +1789,7 @@ proxy_nack_handler(coap_session_t *session, remove_proxy_association(session, 1); break; case COAP_NACK_ICMP_ISSUE: + case COAP_NACK_BAD_RESPONSE: default: break; } diff --git a/include/coap3/coap_event.h b/include/coap3/coap_event.h index 2b5cb014..bda21ef5 100644 --- a/include/coap3/coap_event.h +++ b/include/coap3/coap_event.h @@ -91,7 +91,13 @@ typedef enum { * The session will still contain valid data when the event handler is * called. */ - COAP_EVENT_SERVER_SESSION_DEL = 0x4002 + COAP_EVENT_SERVER_SESSION_DEL = 0x4002, + +/* + * Received packet formatting errors + */ + /** Triggered when badly formatted packet received */ + COAP_EVENT_BAD_PACKET = 0x5001 } coap_event_t; diff --git a/include/coap3/coap_io.h b/include/coap3/coap_io.h index ef2e72d8..e4f3f0e0 100644 --- a/include/coap3/coap_io.h +++ b/include/coap3/coap_io.h @@ -71,7 +71,8 @@ typedef enum { COAP_NACK_NOT_DELIVERABLE, COAP_NACK_RST, COAP_NACK_TLS_FAILED, - COAP_NACK_ICMP_ISSUE + COAP_NACK_ICMP_ISSUE, + COAP_NACK_BAD_RESPONSE } coap_nack_reason_t; #endif /* COAP_IO_H_ */ diff --git a/man/coap_handler.txt.in b/man/coap_handler.txt.in index 9f453b45..200842ff 100644 --- a/man/coap_handler.txt.in +++ b/man/coap_handler.txt.in @@ -144,6 +144,7 @@ COAP_NACK_NOT_DELIVERABLE COAP_NACK_RST COAP_NACK_TLS_FAILED COAP_NACK_ICMP_ISSUE +COAP_NACK_BAD_RESPONSE ---- _sent_ can be NULL. _mid_ can be used for determing which is the transmitting @@ -217,6 +218,10 @@ COAP_EVENT_XMIT_BLOCK_FAIL 0x3002 */ COAP_EVENT_SERVER_SESSION_NEW 0x4001 COAP_EVENT_SERVER_SESSION_DEL 0x4002 +/** + * Unrecognizable received packet events + */ +COAP_EVENT_BAD_PACKET 0x5001 ---- EXAMPLES diff --git a/src/net.c b/src/net.c index 98859443..f3c7c3a9 100644 --- a/src/net.c +++ b/src/net.c @@ -2054,6 +2054,7 @@ coap_handle_dgram(coap_context_t *ctx, coap_session_t *session, goto error; if (!coap_pdu_parse(session->proto, msg, msg_len, pdu)) { + coap_handle_event(session->context, COAP_EVENT_BAD_PACKET, session); coap_log(LOG_WARNING, "discard malformed PDU\n"); goto error; } @@ -3163,6 +3164,7 @@ coap_dispatch(coap_context_t *context, coap_session_t *session, coap_pdu_t *response; coap_opt_filter_t opt_filter; int is_ping_rst; + int packet_is_bad = 0; if (LOG_DEBUG <= coap_get_log_level()) { /* FIXME: get debug to work again ** @@ -3189,8 +3191,10 @@ coap_dispatch(coap_context_t *context, coap_session_t *session, /* Flush out any entries on session->delayqueue */ coap_session_connected(session); } - if (coap_option_check_critical(session, pdu, &opt_filter) == 0) + if (coap_option_check_critical(session, pdu, &opt_filter) == 0) { + packet_is_bad = 1; goto cleanup; + } #if COAP_SERVER_SUPPORT /* if sent code was >= 64 the message might have been a @@ -3271,6 +3275,7 @@ coap_dispatch(coap_context_t *context, coap_session_t *session, coap_remove_from_queue(&context->sendqueue, session, pdu->mid, &sent); /* check for unknown critical options */ if (coap_option_check_critical(session, pdu, &opt_filter) == 0) { + packet_is_bad = 1; coap_send_rst(session, pdu); goto cleanup; } @@ -3278,7 +3283,7 @@ coap_dispatch(coap_context_t *context, coap_session_t *session, case COAP_MESSAGE_CON: /* check for unknown critical options */ if (coap_option_check_critical(session, pdu, &opt_filter) == 0) { - + packet_is_bad = 1; if (COAP_PDU_IS_REQUEST(pdu)) { response = coap_new_error_response(pdu, COAP_RESPONSE_CODE(402), &opt_filter); @@ -3322,6 +3327,8 @@ coap_dispatch(coap_context_t *context, coap_session_t *session, if (context->ping_handler) { context->ping_handler(session, pdu, pdu->mid); } + } else { + packet_is_bad = 1; } coap_log(LOG_DEBUG, "dropped message with invalid code (%d.%02d)\n", COAP_RESPONSE_CLASS(pdu->code), @@ -3345,6 +3352,16 @@ coap_dispatch(coap_context_t *context, coap_session_t *session, } cleanup: + if (packet_is_bad) { + if (sent) { + if (context->nack_handler) { + context->nack_handler(session, sent->pdu, COAP_NACK_BAD_RESPONSE, sent->id); + } + } + else { + coap_handle_event(context, COAP_EVENT_BAD_PACKET, session); + } + } coap_delete_node(sent); }