From ac83b32b33195551fc5b8fb732fe4c10252cdbea Mon Sep 17 00:00:00 2001 From: kkrentz Date: Tue, 17 Sep 2024 08:38:08 +0200 Subject: [PATCH] Improve MTU handling by: - Correcting Contiki-NG's value of COAP_DEFAULT_MAX_PDU_RX_SIZE - Denying to create PDUs longer than COAP_DEFAULT_MAX_PDU_RX_SIZE - Using the MTU setter, thereby not overriding stack-specific limits - Using existing constants for L4-specific header sizes --- include/coap3/coap_pdu_internal.h | 2 +- src/coap_pdu.c | 10 ++++++---- src/coap_session.c | 14 +++++++++----- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/include/coap3/coap_pdu_internal.h b/include/coap3/coap_pdu_internal.h index aabc362a8b..db6d5ae2ce 100644 --- a/include/coap3/coap_pdu_internal.h +++ b/include/coap3/coap_pdu_internal.h @@ -77,7 +77,7 @@ #if defined(WITH_LWIP) #define COAP_DEFAULT_MAX_PDU_RX_SIZE (COAP_MAX_MESSAGE_SIZE_TCP16+4UL) #elif defined(WITH_CONTIKI) -#define COAP_DEFAULT_MAX_PDU_RX_SIZE (sizeof(coap_packet_t) + UIP_APPDATA_SIZE) +#define COAP_DEFAULT_MAX_PDU_RX_SIZE (UIP_APPDATA_SIZE) #elif (UINT_MAX < (8UL*1024*1024+256)) #define COAP_DEFAULT_MAX_PDU_RX_SIZE (1500UL) #elif defined(RIOT_VERSION) && defined(COAP_DISABLE_TCP) diff --git a/src/coap_pdu.c b/src/coap_pdu.c index e116a1abfd..569ac0d70b 100644 --- a/src/coap_pdu.c +++ b/src/coap_pdu.c @@ -118,14 +118,16 @@ coap_pdu_init(coap_pdu_type_t type, coap_pdu_code_t code, coap_mid_t mid, if (!pdu) return NULL; -#if defined(WITH_CONTIKI) || defined(WITH_LWIP) - assert(size <= COAP_DEFAULT_MAX_PDU_RX_SIZE); - if (size > COAP_DEFAULT_MAX_PDU_RX_SIZE) - return NULL; +#if COAP_DEFAULT_MAX_PDU_RX_SIZE <= COAP_MAX_MESSAGE_SIZE_TCP16 + /* on TCP, the CoAP header will also have a maximum length of 4 bytes */ pdu->max_hdr_size = COAP_PDU_MAX_UDP_HEADER_SIZE; #else pdu->max_hdr_size = COAP_PDU_MAX_TCP_HEADER_SIZE; #endif + if (size > ((size_t)COAP_DEFAULT_MAX_PDU_RX_SIZE - pdu->max_hdr_size)) { + coap_free_type(COAP_PDU, pdu); + return NULL; + } #ifdef WITH_LWIP pdu->pbuf = pbuf_alloc(PBUF_TRANSPORT, size + pdu->max_hdr_size, PBUF_RAM); diff --git a/src/coap_session.c b/src/coap_session.c index 7dd7e0b82e..5e5c380505 100644 --- a/src/coap_session.c +++ b/src/coap_session.c @@ -443,7 +443,7 @@ coap_make_session(coap_proto_t proto, coap_session_type_t type, session->mtu = endpoint->default_mtu; else #endif /* COAP_SERVER_SUPPORT */ - session->mtu = COAP_DEFAULT_MTU; + coap_session_set_mtu(session, COAP_DEFAULT_MTU); session->block_mode = context->block_mode; if (proto == COAP_PROTO_DTLS) { session->tls_overhead = 29; @@ -604,10 +604,14 @@ coap_session_max_pdu_size_internal(const coap_session_t *session, size_t max_with_header) { #if COAP_DISABLE_TCP (void)session; - return max_with_header > 4 ? max_with_header - 4 : 0; + return max_with_header > COAP_PDU_MAX_UDP_HEADER_SIZE + ? max_with_header - COAP_PDU_MAX_UDP_HEADER_SIZE + : 0; #else /* !COAP_DISABLE_TCP */ if (COAP_PROTO_NOT_RELIABLE(session->proto)) - return max_with_header > 4 ? max_with_header - 4 : 0; + return max_with_header > COAP_PDU_MAX_UDP_HEADER_SIZE + ? max_with_header - COAP_PDU_MAX_UDP_HEADER_SIZE + : 0; /* we must assume there is no token to be on the safe side */ if (max_with_header <= 2) return 0; @@ -618,7 +622,7 @@ coap_session_max_pdu_size_internal(const coap_session_t *session, else if (max_with_header <= COAP_MAX_MESSAGE_SIZE_TCP16 + 4) return max_with_header - 4; else - return max_with_header - 6; + return max_with_header - COAP_PDU_MAX_TCP_HEADER_SIZE; #endif /* !COAP_DISABLE_TCP */ } @@ -741,7 +745,7 @@ coap_session_send_csm(coap_session_t *session) { session->state = COAP_SESSION_STATE_CSM; session->partial_write = 0; if (session->mtu == 0) - session->mtu = COAP_DEFAULT_MTU; /* base value */ + coap_session_set_mtu(session, COAP_DEFAULT_MTU); /* base value */ pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_SIGNALING_CODE_CSM, 0, 20); if (pdu == NULL || coap_add_option_internal(pdu, COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE,