diff --git a/include/coap2/coap_session.h b/include/coap2/coap_session.h index 039965e3..afb37bef 100644 --- a/include/coap2/coap_session.h +++ b/include/coap2/coap_session.h @@ -63,7 +63,7 @@ typedef struct coap_session_t { coap_session_state_t state; /**< current state of relationaship with peer */ unsigned ref; /**< reference count from queues */ unsigned tls_overhead; /**< overhead of TLS layer */ - unsigned mtu; /**< path or CSM mtu */ + uint64_t mtu; /**< path or CSM mtu */ coap_address_t local_if; /**< optional local interface address */ UT_hash_handle hh; coap_addr_tuple_t addr_info; /**< key: remote/local address info */ @@ -74,6 +74,7 @@ typedef struct coap_session_t { void *tls; /**< security parameters */ uint16_t tx_mid; /**< the last message id that was used in this session */ uint8_t con_active; /**< Active CON request sent */ + uint8_t csm_block_supported; /**< CSM TCP blocks supported */ coap_tid_t last_ping_mid; /**< the last keepalive message id that was used in this session */ struct coap_queue_t *delayqueue; /**< list of delayed messages waiting to be sent */ size_t partial_write; /**< if > 0 indicates number of bytes already written from the pdu at the head of sendqueue */ diff --git a/include/coap2/pdu.h b/include/coap2/pdu.h index 6b4d9aef..2487bc31 100644 --- a/include/coap2/pdu.h +++ b/include/coap2/pdu.h @@ -45,10 +45,10 @@ struct coap_session_t; #ifndef COAP_DEFAULT_MAX_PDU_RX_SIZE #if defined(WITH_CONTIKI) || defined(WITH_LWIP) -#define COAP_DEFAULT_MAX_PDU_RX_SIZE (COAP_MAX_MESSAGE_SIZE_TCP16+4) +#define COAP_DEFAULT_MAX_PDU_RX_SIZE (COAP_MAX_MESSAGE_SIZE_TCP16+4UL) #else /* 8 MiB max-message-size plus some space for options */ -#define COAP_DEFAULT_MAX_PDU_RX_SIZE (8*1024*1024+256) +#define COAP_DEFAULT_MAX_PDU_RX_SIZE (8UL*1024*1024+256) #endif #endif /* COAP_DEFAULT_MAX_PDU_RX_SIZE */ diff --git a/src/coap_session.c b/src/coap_session.c index 61047485..a5bfcf7d 100644 --- a/src/coap_session.c +++ b/src/coap_session.c @@ -314,11 +314,14 @@ void coap_session_send_csm(coap_session_t *session) { session->partial_write = 0; if (session->mtu == 0) session->mtu = COAP_DEFAULT_MTU; /* base value */ - pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_SIGNALING_CSM, 0, 16); + pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_SIGNALING_CSM, 0, 20); if ( pdu == NULL || coap_add_option(pdu, COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE, coap_encode_var_safe(buf, sizeof(buf), COAP_DEFAULT_MAX_PDU_RX_SIZE), buf) == 0 + || coap_add_option(pdu, COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER, + coap_encode_var_safe(buf, sizeof(buf), + 0), buf) == 0 || coap_pdu_encode_header(pdu, session->proto) == 0 ) { coap_session_disconnected(session, COAP_NACK_NOT_DELIVERABLE); diff --git a/src/net.c b/src/net.c index 458e4895..18c60a4a 100644 --- a/src/net.c +++ b/src/net.c @@ -1003,6 +1003,25 @@ coap_send(coap_session_t *session, coap_pdu_t *pdu) { goto error; } +#if !COAP_DISABLE_TCP + if (COAP_PROTO_RELIABLE(session->proto) && !session->csm_block_supported) { + /* + * Need to check that this instance is not sending any block options as the + * remote end via CSM has not informed us that there is support + * https://tools.ietf.org/html/rfc8323#section-5.3.2 + * Note that this also includes BERT which is application specific. + */ + coap_opt_iterator_t opt_iter; + + if (coap_check_option(pdu, COAP_OPTION_BLOCK1, &opt_iter) != NULL) { + goto error; + } + if (coap_check_option(pdu, COAP_OPTION_BLOCK2, &opt_iter) != NULL) { + goto error; + } + } +#endif /* !COAP_DISABLE_TCP */ + bytes_written = coap_send_pdu( session, pdu, NULL ); if (bytes_written == COAP_PDU_DELAYED) { @@ -1337,6 +1356,14 @@ coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now) if (n == len) { size_t size = coap_pdu_parse_size(session->proto, session->read_header, hdr_size); + if (size > COAP_DEFAULT_MAX_PDU_RX_SIZE) { + coap_log(LOG_WARNING, + "** %s: incoming PDU length too large (%zu > %lu)\n", + coap_session_str(session), + size, COAP_DEFAULT_MAX_PDU_RX_SIZE); + bytes_read = -1; + break; + } session->partial_pdu = coap_pdu_init(0, 0, 0, size); if (session->partial_pdu == NULL) { bytes_read = -1; @@ -2395,7 +2422,7 @@ handle_signaling(coap_context_t *context, coap_session_t *session, coap_session_set_mtu(session, coap_decode_var_bytes(coap_opt_value(option), coap_opt_length(option))); } else if (opt_iter.type == COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER) { - /* ... */ + session->csm_block_supported = 1; } } if (session->state == COAP_SESSION_STATE_CSM)