lwm2m_coap: DTLS Cid Length

This commit is contained in:
nick 2024-02-12 13:31:38 +02:00
parent 9fa36c7a2d
commit c2268595eb
23 changed files with 707 additions and 43 deletions

View File

@ -1019,6 +1019,16 @@ transport:
# CoAP DTLS bind port
bind_port: "${COAP_DTLS_BIND_PORT:5684}"
# Server DTLS credentials
# CoAP DTLS connection ID length. RFC 9146, Connection Identifier for DTLS 1.2
# Default: off
# Control usage of DTLS connection ID length (CID).
# - 'off' to deactivate it.
# - 'on' to activate Connection ID support (same as CID 0 or more 0).
# - A positive value defines generated CID size in bytes.
# - A value of 0 means we accept using CID but will not generate one for foreign peer (enables support but not for incoming traffic).
# - 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:}"
credentials:
# Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore)
type: "${COAP_DTLS_CREDENTIALS_TYPE:PEM}"
@ -1056,6 +1066,16 @@ transport:
dtls:
# RFC7925_RETRANSMISSION_TIMEOUT_IN_MILLISECONDS = 9000
retransmission_timeout: "${LWM2M_DTLS_RETRANSMISSION_TIMEOUT_MS:9000}"
# CoAP DTLS connection ID length for LWM2M. RFC 9146, Connection Identifier for DTLS 1.2
# Default: off
# Control usage of DTLS connection ID length (CID).
# - 'off' to deactivate it.
# - 'on' to activate Connection ID support (same as CID 0 or more 0).
# - A positive value defines generated CID size in bytes.
# - A value of 0 means we accept using CID but will not generate one for foreign peer (enables support but not for incoming traffic).
# - A value between 0 and <= 4: SingleNodeConnectionIdGenerator is used
# - A value that are > 4: MultiNodeConnectionIdGenerator is used
connection_id_length: "${LWM2M_DTLS_CONNECTION_ID_LENGTH:}"
server:
# LwM2M Server ID
id: "${LWM2M_SERVER_ID:123}"

View File

@ -236,7 +236,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte
getWsClient().waitForReply();
getWsClient().registerWaitForUpdate();
createNewClient(security, null, coapConfig, false, endpoint);
createNewClient(security, null, coapConfig, false, endpoint, null);
deviceId = device.getId().getId().toString();
awaitObserveReadAll(0, deviceId);
String msg = getWsClient().waitForUpdate();
@ -304,14 +304,15 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte
this.resources = resources;
}
public void createNewClient(Security security, Security securityBs, Configuration coapConfig, boolean isRpc, String endpoint) throws Exception {
public void createNewClient(Security security, Security securityBs, Configuration coapConfig, boolean isRpc,
String endpoint, Integer clientDtlsCidLength) throws Exception {
this.clientDestroy();
lwM2MTestClient = new LwM2MTestClient(this.executor, endpoint);
try (ServerSocket socket = new ServerSocket(0)) {
int clientPort = socket.getLocalPort();
lwM2MTestClient.init(security, securityBs, coapConfig, clientPort, isRpc,
this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest, isWriteAttribute);
this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest, isWriteAttribute, clientDtlsCidLength);
}
}

View File

@ -53,7 +53,7 @@ public class Lwm2mTestHelper {
public enum LwM2MClientState {
ON_INIT(1, "onInit"),
ON_INIT(0, "onInit"),
ON_BOOTSTRAP_STARTED(1, "onBootstrapStarted"),
ON_BOOTSTRAP_SUCCESS(2, "onBootstrapSuccess"),
ON_BOOTSTRAP_FAILURE(3, "onBootstrapFailure"),
@ -70,7 +70,9 @@ public class Lwm2mTestHelper {
ON_DEREGISTRATION_SUCCESS(13, "onDeregistrationSuccess"),
ON_DEREGISTRATION_FAILURE(14, "onDeregistrationFailure"),
ON_DEREGISTRATION_TIMEOUT(15, "onDeregistrationTimeout"),
ON_EXPECTED_ERROR(16, "onUnexpectedError");
ON_EXPECTED_ERROR(16, "onUnexpectedError"),
ON_READ_CONNECTION_ID (17, "onReadConnection"),
ON_WRITE_CONNECTION_ID (18, "onWriteConnection");
public int code;
public String type;

View File

@ -0,0 +1,81 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.client;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.scandium.dtls.ClientHandshaker;
import org.eclipse.californium.scandium.dtls.DTLSContext;
import org.eclipse.californium.scandium.dtls.HandshakeException;
import org.eclipse.californium.scandium.dtls.Handshaker;
import org.eclipse.californium.scandium.dtls.SessionAdapter;
import org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState;
import java.util.Map;
import java.util.Set;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_READ_CONNECTION_ID;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_WRITE_CONNECTION_ID;
@Slf4j
public class DtlsSessionLogger extends SessionAdapter {
private final Set<LwM2MClientState> clientStates;
private final Map<LwM2MClientState, Integer> clientDtlsCid;
public DtlsSessionLogger(Set<LwM2MClientState> clientStates, Map<LwM2MClientState, Integer> clientDtlsCid) {
this.clientStates = clientStates;
this.clientDtlsCid = clientDtlsCid;
}
@Override
public void handshakeStarted(Handshaker handshaker) throws HandshakeException {
if (handshaker instanceof ClientHandshaker) {
log.info("DTLS Full Handshake initiated by client : STARTED ...");
}
}
@Override
public void contextEstablished(Handshaker handshaker, DTLSContext establishedContext) throws HandshakeException {
if (handshaker instanceof ClientHandshaker) {
log.warn("DTLS initiated by client: SUCCEED, WriteConnectionId: [{}], ReadConnectionId: [{}]", establishedContext.getWriteConnectionId(), establishedContext.getReadConnectionId());
clientStates.add(ON_WRITE_CONNECTION_ID);
clientStates.add(ON_READ_CONNECTION_ID);
Integer lenWrite = establishedContext.getWriteConnectionId() == null ? null : establishedContext.getWriteConnectionId().getBytes().length;
Integer lenRead = establishedContext.getReadConnectionId() == null ? null : establishedContext.getReadConnectionId().getBytes().length;
clientDtlsCid.put(ON_WRITE_CONNECTION_ID, lenWrite);
clientDtlsCid.put(ON_READ_CONNECTION_ID, lenRead);
}
}
@Override
public void handshakeFailed(Handshaker handshaker, Throwable error) {
// get cause
String cause;
if (error != null) {
if (error.getMessage() != null) {
cause = error.getMessage();
} else {
cause = error.getClass().getName();
}
} else {
cause = "unknown cause";
}
if (handshaker instanceof ClientHandshaker) {
log.info("DTLS Full Handshake initiated by client : FAILED ({})", cause);
}
}
}

View File

@ -18,7 +18,6 @@ package org.thingsboard.server.transport.lwm2m.client;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.californium.scandium.config.DtlsConfig;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.leshan.client.LeshanClient;
import org.eclipse.leshan.client.LeshanClientBuilder;
@ -62,11 +61,15 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_CONNECTION_ID_LENGTH;
import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY;
import static org.eclipse.leshan.core.LwM2mId.ACCESS_CONTROL;
import static org.eclipse.leshan.core.LwM2mId.DEVICE;
import static org.eclipse.leshan.core.LwM2mId.FIRMWARE;
@ -103,6 +106,7 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INST
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_12;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.TEMPERATURE_SENSOR;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resources;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.setDtlsConnectorConfigCidLength;
@Slf4j
@ -119,12 +123,13 @@ public class LwM2MTestClient {
private LwM2MLocationParams locationParams;
private LwM2mTemperatureSensor lwM2MTemperatureSensor;
private Set<LwM2MClientState> clientStates;
private Map<LwM2MClientState, Integer> clientDtlsCid;
private LwM2mUplinkMsgHandler defaultLwM2mUplinkMsgHandlerTest;
private LwM2mClientContext clientContext;
public void init(Security security, Security securityBs,Configuration coapConfig, int port, boolean isRpc,
LwM2mUplinkMsgHandler defaultLwM2mUplinkMsgHandler,
LwM2mClientContext clientContext, boolean isWriteAttribute) throws InvalidDDFFileException, IOException {
LwM2mClientContext clientContext, boolean isWriteAttribute, Integer cIdLength) throws InvalidDDFFileException, IOException {
Assert.assertNull("client already initialized", leshanClient);
this.defaultLwM2mUplinkMsgHandlerTest = defaultLwM2mUplinkMsgHandler;
this.clientContext = clientContext;
@ -188,6 +193,10 @@ public class LwM2MTestClient {
protected DtlsConnectorConfig.Builder createRootDtlsConnectorConfigBuilder(
Configuration configuration) {
DtlsConnectorConfig.Builder builder = super.createRootDtlsConnectorConfigBuilder(configuration);
// Add DTLS Session lifecycle logger
builder.setSessionListener(new DtlsSessionLogger(clientStates, clientDtlsCid));
return builder;
};
};
@ -213,20 +222,18 @@ public class LwM2MTestClient {
// Set some DTLS stuff
// These configuration values are always overwritten by CLI therefore set them to transient.
clientCoapConfig.setTransient(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY);
clientCoapConfig.setTransient(DtlsConfig.DTLS_CONNECTION_ID_LENGTH);
clientCoapConfig.setTransient(DTLS_RECOMMENDED_CIPHER_SUITES_ONLY);
clientCoapConfig.setTransient(DTLS_CONNECTION_ID_LENGTH);
boolean supportDeprecatedCiphers = false;
clientCoapConfig.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, !supportDeprecatedCiphers);
/**
* "Control usage of DTLS connection ID.", //
* "- 'on' to activate Connection ID support (same as -cid 0)", //
* "- 'off' to deactivate it", //
* "- Positive value define the size in byte of CID generated.", //
* "- 0 value means we accept to use CID but will not generated one for foreign peer.", //
* "Default: off"
*/
Integer cid = null;
clientCoapConfig.set(DtlsConfig.DTLS_CONNECTION_ID_LENGTH, cid);
clientCoapConfig.set(DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, !supportDeprecatedCiphers);
if (cIdLength!= null) {
setDtlsConnectorConfigCidLength(clientCoapConfig, cIdLength);
}
if (cIdLength!= null) {
setDtlsConnectorConfigCidLength(clientCoapConfig, cIdLength);
}
// Set Californium Configuration
endpointsBuilder.setConfiguration(clientCoapConfig);
@ -279,6 +286,7 @@ public class LwM2MTestClient {
builder.setSharedExecutor(executor);
clientStates = new HashSet<>();
clientDtlsCid = new HashMap<>();
clientStates.add(ON_INIT);
leshanClient = builder.build();

View File

@ -59,7 +59,7 @@ public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest {
createDeviceProfile(transportConfiguration);
LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_WITHOUT_FW_INFO));
final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO);
createNewClient(SECURITY_NO_SEC, null, COAP_CONFIG, false, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO);
createNewClient(SECURITY_NO_SEC, null, COAP_CONFIG, false, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO, null);
awaitObserveReadAll(0, device.getId().getId().toString());
device.setFirmwareId(createFirmware().getId());
@ -84,7 +84,7 @@ public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest {
createDeviceProfile(transportConfiguration);
LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_OTA5));
final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_OTA5);
createNewClient(SECURITY_NO_SEC, null, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA5);
createNewClient(SECURITY_NO_SEC, null, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA5, null);
awaitObserveReadAll(9, device.getId().getId().toString());
device.setFirmwareId(createFirmware().getId());
@ -114,7 +114,7 @@ public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest {
createDeviceProfile(transportConfiguration);
LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_OTA9));
final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_OTA9);
createNewClient(SECURITY_NO_SEC, null, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA9);
createNewClient(SECURITY_NO_SEC, null, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA9, null);
awaitObserveReadAll(9, device.getId().getId().toString());
device.setSoftwareId(createSoftware().getId());

View File

@ -91,7 +91,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg
private void initRpc () throws Exception {
String endpoint = DEVICE_ENDPOINT_RPC_PREF + endpointSequence.incrementAndGet();
createNewClient(SECURITY_NO_SEC, null, COAP_CONFIG, true, endpoint);
createNewClient(SECURITY_NO_SEC, null, COAP_CONFIG, true, endpoint, null);
expectedObjects = ConcurrentHashMap.newKeySet();
expectedObjectIdVers = ConcurrentHashMap.newKeySet();
expectedInstances = ConcurrentHashMap.newKeySet();

View File

@ -196,7 +196,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M
boolean isStartLw) throws Exception {
createDeviceProfile(transportConfiguration);
final Device device = createDevice(deviceCredentials, endpoint);
createNewClient(security, securityBs, coapConfig, true, endpoint);
createNewClient(security, securityBs, coapConfig, true, endpoint, null);
lwM2MTestClient.start(isStartLw);
if (isAwaitObserveReadAll) {
awaitObserveReadAll(0, device.getId().getId().toString());
@ -244,7 +244,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M
createDeviceProfile(transportConfiguration);
final Device device = createDevice(deviceCredentials, endpoint);
String deviceIdStr = device.getId().getId().toString();
createNewClient(security, securityBs, coapConfig, true, endpoint);
createNewClient(security, securityBs, coapConfig, true, endpoint, null);
lwM2MTestClient.start(true);
awaitObserveReadAll(0, deviceIdStr);
await(awaitAlias)

View File

@ -0,0 +1,38 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.security.cid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.test.context.TestPropertySource;
import org.thingsboard.server.dao.service.DaoSqlTest;
@TestPropertySource(properties = {
"transport.lwm2m.dtls.connection_id_length=0"
})
@DaoSqlTest
@Slf4j
public abstract class AbstractSecurityLwM2MIntegrationDtlsCidLength0Test extends AbstractSecurityLwM2MIntegrationDtlsCidLengthTest {
protected void testNoSecDtlsCidLength(Integer dtlsCidLength) throws Exception {
testNoSecDtlsCidLength(dtlsCidLength, 0);
}
protected void testPskDtlsCidLength(Integer dtlsCidLength) throws Exception {
testPskDtlsCidLength(dtlsCidLength, 0);
}
}

View File

@ -0,0 +1,37 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.security.cid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.test.context.TestPropertySource;
import org.thingsboard.server.dao.service.DaoSqlTest;
@TestPropertySource(properties = {
"transport.lwm2m.dtls.connection_id_length=3"
})
@DaoSqlTest
@Slf4j
public abstract class AbstractSecurityLwM2MIntegrationDtlsCidLength3Test extends AbstractSecurityLwM2MIntegrationDtlsCidLengthTest {
protected void testNoSecDtlsCidLength(Integer dtlsCidLength) throws Exception {
testNoSecDtlsCidLength(dtlsCidLength, 3);
}
protected void testPskDtlsCidLength(Integer dtlsCidLength) throws Exception {
testPskDtlsCidLength(dtlsCidLength, 3);
}
}

View File

@ -0,0 +1,38 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.security.cid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.test.context.TestPropertySource;
import org.thingsboard.server.dao.service.DaoSqlTest;
@TestPropertySource(properties = {
"transport.lwm2m.dtls.connection_id_length="
})
@DaoSqlTest
@Slf4j
public abstract class AbstractSecurityLwM2MIntegrationDtlsCidLengthNullTest extends AbstractSecurityLwM2MIntegrationDtlsCidLengthTest {
protected void testNoSecDtlsCidLength(Integer dtlsCidLength) throws Exception {
testNoSecDtlsCidLength(dtlsCidLength, null);
}
protected void testPskDtlsCidLength(Integer dtlsCidLength) throws Exception {
testPskDtlsCidLength(dtlsCidLength, null);
}
}

View File

@ -0,0 +1,133 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.security.cid;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.leshan.client.californium.endpoint.CaliforniumClientEndpoint;
import org.eclipse.leshan.client.californium.endpoint.CaliforniumClientEndpointsProvider;
import org.eclipse.leshan.client.object.Security;
import org.eclipse.leshan.core.util.Hex;
import org.junit.Assert;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.device.credentials.lwm2m.AbstractLwM2MClientSecurityCredential;
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials;
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredential;
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState;
import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.awaitility.Awaitility.await;
import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_CONNECTION_ID_LENGTH;
import static org.eclipse.leshan.client.object.Security.psk;
import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.PSK;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_INIT;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_READ_CONNECTION_ID;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_STARTED;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_UPDATE_SUCCESS;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_WRITE_CONNECTION_ID;
@DaoSqlTest
@Slf4j
public abstract class AbstractSecurityLwM2MIntegrationDtlsCidLengthTest extends AbstractSecurityLwM2MIntegrationTest {
protected AbstractLwM2MClientSecurityCredential clientCredentials;
protected Security security;
protected Lwm2mDeviceProfileTransportConfiguration transportConfiguration;
protected LwM2MDeviceCredentials deviceCredentials;
protected String clientEndpoint;
protected LwM2MSecurityMode lwM2MSecurityMode;
protected String awaitAlias;
protected final Random randomSuffix = new Random();
protected final Set<LwM2MClientState> expectedStatusesRegistrationLwm2mDtlsCidSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS, ON_READ_CONNECTION_ID, ON_WRITE_CONNECTION_ID));
protected void testNoSecDtlsCidLength(Integer dtlsCidLength, Integer serverDtlsCidLength) throws Exception {
initDeviceCredentialsNoSek();
basicTestConnectionDtlsCidLength(dtlsCidLength, serverDtlsCidLength);
}
protected void testPskDtlsCidLength(Integer dtlsCidLength, Integer serverDtlsCidLength) throws Exception {
initDeviceCredentialsPsk();
basicTestConnectionDtlsCidLength(dtlsCidLength, serverDtlsCidLength);
}
protected void initDeviceCredentialsNoSek() {
clientEndpoint = CLIENT_ENDPOINT_NO_SEC + "_" + randomSuffix.nextInt(100);
deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint));
}
protected void initDeviceCredentialsPsk() {
int suf = randomSuffix.nextInt(10);
clientEndpoint = CLIENT_ENDPOINT_PSK + "_" + suf;
String identity = CLIENT_PSK_IDENTITY + "_" + suf;
clientCredentials = new PSKClientCredential();
clientCredentials.setEndpoint(clientEndpoint);
((PSKClientCredential)clientCredentials).setIdentity(identity);
clientCredentials.setKey(CLIENT_PSK_KEY);
security = psk(SECURE_URI,
shortServerId,
identity.getBytes(StandardCharsets.UTF_8),
Hex.decodeHex(CLIENT_PSK_KEY.toCharArray()));
deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK, false);
}
protected void basicTestConnectionDtlsCidLength(Integer clientDtlsCidLength,
Integer serverDtlsCidLength) throws Exception {
createDeviceProfile(transportConfiguration);
final Device device = createDevice(deviceCredentials, clientEndpoint);
device.getId().getId().toString();
createNewClient(security, null, COAP_CONFIG, true, clientEndpoint, clientDtlsCidLength);
lwM2MTestClient.start(true);
await(awaitAlias)
.atMost(40, TimeUnit.SECONDS)
.until(() -> lwM2MTestClient.getClientStates().contains(ON_UPDATE_SUCCESS));
Assert.assertTrue(lwM2MTestClient.getClientStates().containsAll(expectedStatusesRegistrationLwm2mSuccess));
Configuration clientCoapConfig = ((CaliforniumClientEndpoint)((CaliforniumClientEndpointsProvider)lwM2MTestClient
.getLeshanClient().getEndpointsProvider().toArray()[0]).getEndpoints().toArray()[0]).getCoapEndpoint().getConfig();
Assert.assertEquals(clientDtlsCidLength, clientCoapConfig.get(DTLS_CONNECTION_ID_LENGTH));
if (security.equals(SECURITY_NO_SEC)) {
Assert.assertTrue(lwM2MTestClient.getClientDtlsCid().isEmpty());
} else {
Assert.assertEquals(2L, lwM2MTestClient.getClientDtlsCid().size());
Assert.assertTrue(lwM2MTestClient.getClientDtlsCid().keySet().contains(ON_READ_CONNECTION_ID));
Assert.assertTrue(lwM2MTestClient.getClientDtlsCid().keySet().contains(ON_WRITE_CONNECTION_ID));
if (serverDtlsCidLength == null) {
Assert.assertNull(lwM2MTestClient.getClientDtlsCid().get(ON_WRITE_CONNECTION_ID));
Assert.assertNull(lwM2MTestClient.getClientDtlsCid().get(ON_READ_CONNECTION_ID));
} else {
Assert.assertEquals(clientDtlsCidLength, lwM2MTestClient.getClientDtlsCid().get(ON_READ_CONNECTION_ID));
if (clientDtlsCidLength == null) {
Assert.assertNull(lwM2MTestClient.getClientDtlsCid().get(ON_READ_CONNECTION_ID));
} else {
Assert.assertEquals(Integer.valueOf(serverDtlsCidLength), lwM2MTestClient.getClientDtlsCid().get(ON_WRITE_CONNECTION_ID));
}
}
}
}
}

View File

@ -0,0 +1,48 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.security.cid.serverDtlsCidLength_0;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.transport.lwm2m.security.cid.AbstractSecurityLwM2MIntegrationDtlsCidLength0Test;
import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.NO_SEC;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE;
public class NoSecLwM2MIntegrationDtlsCidLengthTest extends AbstractSecurityLwM2MIntegrationDtlsCidLength0Test {
@Before
public void setUpNoSecDtlsCidLength() {
security = SECURITY_NO_SEC;
transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(NO_SEC, NONE));
awaitAlias = "await on client state (NoSec_Lwm2m) DtlsCidLength = 0";
}
@Test
public void testWithNoSecConnectLwm2mSuccessClientDtlsCidLength_Null() throws Exception {
testNoSecDtlsCidLength(null);
}
@Test
public void testWithNoSecConnectLwm2mSuccessClientDtlsCidLength_0() throws Exception {
testNoSecDtlsCidLength(0);
}
@Test
public void testWithNoSecConnectLwm2mSuccessClientDtlsCidLength_2() throws Exception {
testNoSecDtlsCidLength(2);
}
}

View File

@ -0,0 +1,46 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.security.cid.serverDtlsCidLength_0;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.transport.lwm2m.security.cid.AbstractSecurityLwM2MIntegrationDtlsCidLength0Test;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE;
public class PskLwm2mIntegrationDtlsCidLengthTest extends AbstractSecurityLwM2MIntegrationDtlsCidLength0Test {
@Before
public void createProfileRpc() {
transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(lwM2MSecurityMode, NONE));
awaitAlias = "await on client state (Psk_Lwm2m) DtlsCidLength = 0";
}
@Test
public void testWithPskConnectLwm2mSuccessClientDtlsCidLength_Null() throws Exception {
testPskDtlsCidLength(null);
}
@Test
public void testWithPskConnectLwm2mSuccessClientDtlsCidLength_0() throws Exception {
testPskDtlsCidLength(0);
}
@Test
public void testWithPskConnectLwm2mSuccessClientDtlsCidLength_2() throws Exception {
testPskDtlsCidLength(2);
}
}

View File

@ -0,0 +1,48 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.security.cid.serverDtlsCidLength_3;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.transport.lwm2m.security.cid.AbstractSecurityLwM2MIntegrationDtlsCidLength3Test;
import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.NO_SEC;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE;
public class NoSecLwM2MIntegrationDtlsCidLengthTest extends AbstractSecurityLwM2MIntegrationDtlsCidLength3Test {
@Before
public void setUpNoSecDtlsCidLength() {
security = SECURITY_NO_SEC;
transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(NO_SEC, NONE));
awaitAlias = "await on client state (NoSec_Lwm2m) DtlsCidLength = 3";
}
@Test
public void testWithNoSecConnectLwm2mSuccessClientDtlsCidLength_Null() throws Exception {
testNoSecDtlsCidLength(null);
}
@Test
public void testWithNoSecConnectLwm2mSuccessClientDtlsCidLength_0() throws Exception {
testNoSecDtlsCidLength(0);
}
@Test
public void testWithNoSecConnectLwm2mSuccessClientDtlsCidLength_2() throws Exception {
testNoSecDtlsCidLength(2);
}
}

View File

@ -0,0 +1,47 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.security.cid.serverDtlsCidLength_3;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.transport.lwm2m.security.cid.AbstractSecurityLwM2MIntegrationDtlsCidLength3Test;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE;
public class PskLwm2mIntegrationDtlsCidLengthTest extends AbstractSecurityLwM2MIntegrationDtlsCidLength3Test {
@Before
public void createProfileRpc() {
transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(lwM2MSecurityMode, NONE));
awaitAlias = "await on client state (Psk_Lwm2m) DtlsCidLength = 3";
}
@Test
public void testWithPskConnectLwm2mSuccessClientDtlsCidLength_Null() throws Exception {
testPskDtlsCidLength(null);
}
@Test
public void testWithPskConnectLwm2mSuccessClientDtlsCidLength_0() throws Exception {
testPskDtlsCidLength(0);
}
@Test
public void testWithPskConnectLwm2mSuccessClientDtlsCidLength_2() throws Exception {
testPskDtlsCidLength(2);
}
}

View File

@ -0,0 +1,48 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.security.cid.serverDtlsCidLength_null;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.transport.lwm2m.security.cid.AbstractSecurityLwM2MIntegrationDtlsCidLengthNullTest;
import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.NO_SEC;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE;
public class NoSecLwM2MIntegrationDtlsCidLengthTest extends AbstractSecurityLwM2MIntegrationDtlsCidLengthNullTest {
@Before
public void setUpNoSecDtlsCidLength() {
security = SECURITY_NO_SEC;
transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(NO_SEC, NONE));
awaitAlias = "await on client state (NoSec_Lwm2m) DtlsCidLength = Null";
}
@Test
public void testWithNoSecConnectLwm2mSuccessClientDtlsCidLength_Null() throws Exception {
testNoSecDtlsCidLength(null);
}
@Test
public void testWithNoSecConnectLwm2mSuccessClientDtlsCidLength_0() throws Exception {
testNoSecDtlsCidLength(0);
}
@Test
public void testWithNoSecConnectLwm2mSuccessClientDtlsCidLength_2() throws Exception {
testNoSecDtlsCidLength(2);
}
}

View File

@ -0,0 +1,47 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.security.cid.serverDtlsCidLength_null;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.transport.lwm2m.security.cid.AbstractSecurityLwM2MIntegrationDtlsCidLengthNullTest;
import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE;
public class PskLwm2mIntegrationDtlsCidLengthTest extends AbstractSecurityLwM2MIntegrationDtlsCidLengthNullTest {
@Before
public void createProfileRpc() {
transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(lwM2MSecurityMode, NONE));
awaitAlias = "await on client state (Psk_Lwm2m) DtlsCidLength = Null";
}
@Test
public void testWithPskConnectLwm2mSuccessClientDtlsCidLength_Null() throws Exception {
testPskDtlsCidLength(null);
}
@Test
public void testWithPskConnectLwm2mSuccessClientDtlsCidLength_0() throws Exception {
testPskDtlsCidLength(0);
}
@Test
public void testWithPskConnectLwm2mSuccessClientDtlsCidLength_2() throws Exception {
testPskDtlsCidLength(2);
}
}

View File

@ -41,6 +41,8 @@ import java.util.Collections;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.eclipse.californium.elements.config.CertificateAuthenticationMode.WANTED;
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_RETRANSMISSION_TIMEOUT;
import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_ROLE;
import static org.eclipse.californium.scandium.config.DtlsConfig.DtlsRole.SERVER_ONLY;
@ -59,6 +61,9 @@ public class TbCoapDtlsSettings {
@Value("${transport.coap.dtls.retransmission_timeout:9000}")
private int dtlsRetransmissionTimeout;
@Value("${transport.coap.dtls.connection_id_length}")
private Integer cIdLength;
@Bean
@ConfigurationProperties(prefix = "transport.coap.dtls.credentials")
public SslCredentialsConfig coapDtlsCredentials() {
@ -93,6 +98,14 @@ public class TbCoapDtlsSettings {
configBuilder.set(DTLS_CLIENT_AUTHENTICATION_MODE, WANTED);
configBuilder.set(DTLS_RETRANSMISSION_TIMEOUT, dtlsRetransmissionTimeout, MILLISECONDS);
configBuilder.set(DTLS_ROLE, SERVER_ONLY);
configBuilder.set(DTLS_CONNECTION_ID_LENGTH, cIdLength);
if (cIdLength != null) {
if (cIdLength > 4) {
configBuilder.set(DTLS_CONNECTION_ID_NODE_ID, 0);
} else {
configBuilder.set(DTLS_CONNECTION_ID_NODE_ID, null);
}
}
configBuilder.setAdvancedCertificateVerifier(
new TbCoapDtlsCertificateVerifier(
transportService,

View File

@ -49,6 +49,7 @@ import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_RETRANSMIS
import static org.thingsboard.server.transport.lwm2m.server.DefaultLwM2mTransportService.PSK_CIPHER_SUITES;
import static org.thingsboard.server.transport.lwm2m.server.DefaultLwM2mTransportService.RPK_OR_X509_CIPHER_SUITES;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MNetworkConfig.getCoapConfig;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.setDtlsConnectorConfigCidLength;
@Slf4j
@Component
@ -113,15 +114,15 @@ public class LwM2MTransportBootstrapService {
serverCoapConfig.setTransient(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY);
serverCoapConfig.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, serverConfig.isRecommendedCiphers());
serverCoapConfig.setTransient(DtlsConfig.DTLS_CONNECTION_ID_LENGTH);
serverCoapConfig.set(DtlsConfig.DTLS_CONNECTION_ID_LENGTH, 6);
serverCoapConfig.set(DTLS_RECOMMENDED_CURVES_ONLY, serverConfig.isRecommendedSupportedGroups());
serverCoapConfig.setTransient(DTLS_RETRANSMISSION_TIMEOUT);
serverCoapConfig.set(DTLS_RETRANSMISSION_TIMEOUT, serverConfig.getDtlsRetransmissionTimeout(), MILLISECONDS);
if (serverConfig.getDtlsCidLength() != null) {
setDtlsConnectorConfigCidLength( serverCoapConfig, serverConfig.getDtlsCidLength());
}
/* Create DTLS Config */
this.setServerWithCredentials(builder);
// Set Californium Configuration

View File

@ -42,6 +42,10 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig {
@Value("${transport.lwm2m.dtls.retransmission_timeout:9000}")
private int dtlsRetransmissionTimeout;
@Getter
@Value("${transport.lwm2m.dtls.connection_id_length:}")
private Integer dtlsCidLength;
@Getter
@Value("${transport.lwm2m.timeout:}")
private Long timeout;

View File

@ -58,6 +58,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_W
import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MNetworkConfig.getCoapConfig;
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FIRMWARE_UPDATE_COAP_RESOURCE;
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.setDtlsConnectorConfigCidLength;
@Slf4j
@Component
@ -165,21 +166,10 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
serverCoapConfig.set(DTLS_RETRANSMISSION_TIMEOUT, config.getDtlsRetransmissionTimeout(), MILLISECONDS);
serverCoapConfig.set(DTLS_ROLE, SERVER_ONLY);
serverCoapConfig.setTransient(DtlsConfig.DTLS_CONNECTION_ID_LENGTH);
/**
* "Control usage of DTLS connection ID.",
* If DTLS_CONNECTION_ID_LENGTH enables the use of a connection id, this node id could be used
* to configure the generation of connection ids specific for node in a multi-node deployment (cluster).
* The value is used as first byte in generated connection ids.
* DTLS connection ID length. <blank> disabled,
* 0 enables support without active use of CID.", defaultValue == null, minimumValue == 0);
* "- 'on' to activate Connection ID support ",
* " (same as -cid 6)",
* "- 'off' to deactivate it",
* "- Positive value define the size in byte of CID generated.",
* "- 0 value means we accept to use CID but will not generated one for foreign peer.",
*/
serverCoapConfig.set(DtlsConfig.DTLS_CONNECTION_ID_LENGTH, 6);
if (config.getDtlsCidLength() != null) {
setDtlsConnectorConfigCidLength( serverCoapConfig, config.getDtlsCidLength());
}
/* Create DTLS Config */
this.setServerWithCredentials(builder);

View File

@ -17,6 +17,7 @@ package org.thingsboard.server.transport.lwm2m.utils;
import com.google.gson.JsonElement;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.leshan.core.model.LwM2mModel;
import org.eclipse.leshan.core.model.ObjectLoader;
import org.eclipse.leshan.core.model.ObjectModel;
@ -55,6 +56,8 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
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.leshan.core.model.ResourceModel.Type.BOOLEAN;
import static org.eclipse.leshan.core.model.ResourceModel.Type.FLOAT;
import static org.eclipse.leshan.core.model.ResourceModel.Type.INTEGER;
@ -425,4 +428,15 @@ public class LwM2MTransportUtil {
}
return newValueStr.equals(oldValueStr);
}
public static void setDtlsConnectorConfigCidLength(Configuration serverCoapConfig, Integer cIdLength) {
serverCoapConfig.setTransient(DTLS_CONNECTION_ID_LENGTH);
serverCoapConfig.setTransient(DTLS_CONNECTION_ID_NODE_ID);
serverCoapConfig.set(DTLS_CONNECTION_ID_LENGTH, cIdLength);
if ( cIdLength > 4) {
serverCoapConfig.set(DTLS_CONNECTION_ID_NODE_ID, 0);
} else {
serverCoapConfig.set(DTLS_CONNECTION_ID_NODE_ID, null);
}
}
}