diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index f642d7fea5..4d69afedb2 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -1302,6 +1302,30 @@ coap: # - A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used # - A value that are > 4: MultiNodeConnectionIdGenerator is used connection_id_length: "${COAP_DTLS_CONNECTION_ID_LENGTH:}" + # Specify the MTU (Maximum Transmission Unit). + # Should be used if LAN MTU is not used, e.g. if IP tunnels are used or if the client uses a smaller value than the LAN MTU. + # Default = 1024 + # Minimum value = 64 + # If set to 0 - LAN MTU is used. + max_transmission_unit: "${COAP_DTLS_MAX_TRANSMISSION_UNIT:1024}" + # DTLS maximum fragment length (RFC 6066, Section 4). + # Default = 1024 + # Possible values: 512, 1024, 2048, 4096. + # If set to 0, the default maximum fragment size of 2^14 bytes (16,384 bytes) is used. + # Without this extension, TLS specifies a fixed maximum plaintext fragment length of 2^14 bytes. + # It may be desirable for constrained clients to negotiate a smaller maximum fragment length due to memory limitations or bandwidth limitations. + # In order to negotiate smaller maximum fragment lengths, + # clients MAY include an extension of type "max_fragment_length" in the (extended) client hello. + # The "extension_data" field of this extension SHALL contain: + # enum { + # 2^9(1) == 512, + # 2^10(2) == 1024, + # 2^11(3) == 2048, + # 2^12(4) == 4096, + # (255) + # } MaxFragmentLength; + # TLS already requires clients and servers to support fragmentation of handshake messages. + max_fragment_length: "${COAP_DTLS_MAX_FRAGMENT_LENGTH:1024}" # Server DTLS credentials credentials: # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) diff --git a/common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsSettings.java b/common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsSettings.java index f83a20b139..2f0127643a 100644 --- a/common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsSettings.java +++ b/common/coap-server/src/main/java/org/thingsboard/server/coapserver/TbCoapDtlsSettings.java @@ -21,6 +21,7 @@ import org.eclipse.californium.elements.config.Configuration; import org.eclipse.californium.elements.util.SslContextUtil; import org.eclipse.californium.scandium.config.DtlsConnectorConfig; import org.eclipse.californium.scandium.dtls.CertificateType; +import org.eclipse.californium.scandium.dtls.MaxFragmentLengthExtension.Length; import org.eclipse.californium.scandium.dtls.x509.SingleCertificateProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -44,6 +45,8 @@ import static org.eclipse.californium.elements.config.CertificateAuthenticationM import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_CLIENT_AUTHENTICATION_MODE; import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_CONNECTION_ID_LENGTH; import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_CONNECTION_ID_NODE_ID; +import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_MAX_FRAGMENT_LENGTH; +import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_MAX_TRANSMISSION_UNIT; import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_RETRANSMISSION_TIMEOUT; import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_ROLE; import static org.eclipse.californium.scandium.config.DtlsConfig.DtlsRole.SERVER_ONLY; @@ -66,6 +69,12 @@ public class TbCoapDtlsSettings { @Value("${coap.dtls.connection_id_length:}") private Integer cIdLength; + @Value("${coap.dtls.max_transmission_unit:1024}") + private Integer maxTransmissionUnit; + + @Value("${coap.dtls.max_fragment_length:1024}") + private Integer maxFragmentLength; + @Bean @ConfigurationProperties(prefix = "coap.dtls.credentials") public SslCredentialsConfig coapDtlsCredentials() { @@ -108,6 +117,15 @@ public class TbCoapDtlsSettings { configBuilder.set(DTLS_CONNECTION_ID_NODE_ID, null); } } + if (maxTransmissionUnit > 0) { + configBuilder.set(DTLS_MAX_TRANSMISSION_UNIT, maxTransmissionUnit); + } + if (maxFragmentLength > 0) { + Length length = fromLength(maxFragmentLength); + if (length != null) { + configBuilder.set(DTLS_MAX_FRAGMENT_LENGTH, length); + } + } configBuilder.setAdvancedCertificateVerifier( new TbCoapDtlsCertificateVerifier( transportService, @@ -127,4 +145,14 @@ public class TbCoapDtlsSettings { return new InetSocketAddress(addr, port); } + + private static Length fromLength(int length) { + for (Length l : Length.values()) { + if (l.length() == length) { + return l; + } + } + return null; + } } + diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index 2c1c0550e1..0c7ff4e43e 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -198,6 +198,30 @@ coap: # - A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used # - A value that are > 4: MultiNodeConnectionIdGenerator is used connection_id_length: "${COAP_DTLS_CONNECTION_ID_LENGTH:}" + # Specify the MTU (Maximum Transmission Unit). + # Should be used if LAN MTU is not used, e.g. if IP tunnels are used or if the client uses a smaller value than the LAN MTU. + # Default = 1024 + # Minimum value = 64 + # If set to 0 - LAN MTU is used. + max_transmission_unit: "${COAP_DTLS_MAX_TRANSMISSION_UNIT:1024}" + # DTLS maximum fragment length (RFC 6066, Section 4). + # Default = 1024 + # Possible values: 512, 1024, 2048, 4096. + # If set to 0, the default maximum fragment size of 2^14 bytes (16,384 bytes) is used. + # Without this extension, TLS specifies a fixed maximum plaintext fragment length of 2^14 bytes. + # It may be desirable for constrained clients to negotiate a smaller maximum fragment length due to memory limitations or bandwidth limitations. + # In order to negotiate smaller maximum fragment lengths, + # clients MAY include an extension of type "max_fragment_length" in the (extended) client hello. + # The "extension_data" field of this extension SHALL contain: + # enum { + # 2^9(1) == 512, + # 2^10(2) == 1024, + # 2^11(3) == 2048, + # 2^12(4) == 4096, + # (255) + # } MaxFragmentLength; + # TLS already requires clients and servers to support fragmentation of handshake messages. + max_fragment_length: "${COAP_DTLS_MAX_FRAGMENT_LENGTH:1024}" # Server DTLS credentials credentials: # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore)