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); }