From 717ffc90facacb5cd1dad37753fc516ea7d559d5 Mon Sep 17 00:00:00 2001 From: Simon Bernard Date: Thu, 4 Jul 2019 11:34:59 +0200 Subject: [PATCH] Avoid to handle 2 bootstrap session at the same time. --- .../bootstrap/BootstrapFailureCause.java | 4 ++ .../bootstrap/DefaultBootstrapHandler.java | 37 +++++++++++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/BootstrapFailureCause.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/BootstrapFailureCause.java index a249a77465..a9f94494a4 100644 --- a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/BootstrapFailureCause.java +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/BootstrapFailureCause.java @@ -23,6 +23,10 @@ public enum BootstrapFailureCause { * The device presented wrong credentials */ UNAUTHORIZED, + /** + * A bootstrap session is already started for the given device. + */ + ALREADY_STARTED, /** * The Bootstrap Server could not find a configuration to send to the device */ diff --git a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/DefaultBootstrapHandler.java b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/DefaultBootstrapHandler.java index 132f195cd8..1cea46fef2 100644 --- a/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/DefaultBootstrapHandler.java +++ b/leshan-server-core/src/main/java/org/eclipse/leshan/server/bootstrap/DefaultBootstrapHandler.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -63,6 +64,7 @@ public class DefaultBootstrapHandler implements BootstrapHandler { protected final LwM2mBootstrapRequestSender sender; protected final BootstrapSessionManager sessionManager; protected final long requestTimeout; + protected final ConcurrentHashMap onGoingSession = new ConcurrentHashMap<>(); public DefaultBootstrapHandler(BootstrapConfigStore store, LwM2mBootstrapRequestSender sender, BootstrapSessionManager sessionManager) { @@ -95,11 +97,19 @@ public BootstrapResponse bootstrap(Identity sender, BootstrapRequest request) { return BootstrapResponse.badRequest("Unauthorized"); } + // check if there is not an ongoing session. + BootstrapSession oldSession = onGoingSession.putIfAbsent(endpoint, session); + if (oldSession != null) { + // Do not start the session if there is already a started one + sessionManager.failed(session, ALREADY_STARTED); + return BootstrapResponse.badRequest("session already started"); + } + // Get the desired bootstrap config for the endpoint final BootstrapConfig cfg = store.get(endpoint, sender); if (cfg == null) { LOG.debug("No bootstrap config for {}/{}", endpoint, sender); - sessionManager.failed(session, NO_BOOTSTRAP_CONFIG); + stopSession(session, NO_BOOTSTRAP_CONFIG); return BootstrapResponse.badRequest("no bootstrap config"); } @@ -118,6 +128,19 @@ protected void startBootstrap(BootstrapSession session, BootstrapConfig cfg) { delete(session, cfg, new ArrayList<>(cfg.toDelete)); } + protected void stopSession(BootstrapSession session, BootstrapFailureCause cause) { + if (!onGoingSession.remove(session.getEndpoint(), session)) { + LOG.warn("Session for endpoint {} / identity {} was already removed", session.getEndpoint(), + session.getIdentity()); + } + // if there is no cause of failure, this is a success + if (cause == null) { + sessionManager.end(session); + } else { + sessionManager.failed(session, cause); + } + } + protected void delete(final BootstrapSession session, final BootstrapConfig cfg, final List pathToDelete) { if (!pathToDelete.isEmpty()) { // get next Security configuration @@ -170,7 +193,7 @@ protected void afterDelete(BootstrapSession session, BootstrapConfig cfg, List