From e27011beaf481fb16ac34e1314bf8181cc7d40ca Mon Sep 17 00:00:00 2001 From: jchrist Date: Tue, 9 Jun 2026 12:30:16 +0300 Subject: [PATCH] fix(smpp): avoid leaking pending session contexts on rejected binds The bind handler stored each session's context in pendingSessionContexts right after authentication, before the per-account connection-limit check. When that check rejected a bind, sessionCreated was never invoked, so the entry was never removed and the map grew unbounded. Defer the insert until after all rejection checks pass, and also remove the entry in sessionDestroyed so every teardown path cleans up. Signed-off-by: jchrist --- .../sendium/core/smpp/server/SmppServerBindHandler.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sendium-core/src/main/java/gr/cytech/sendium/core/smpp/server/SmppServerBindHandler.java b/sendium-core/src/main/java/gr/cytech/sendium/core/smpp/server/SmppServerBindHandler.java index 6269f80..ca28389 100644 --- a/sendium-core/src/main/java/gr/cytech/sendium/core/smpp/server/SmppServerBindHandler.java +++ b/sendium-core/src/main/java/gr/cytech/sendium/core/smpp/server/SmppServerBindHandler.java @@ -41,12 +41,11 @@ public void sessionBindRequested( ) throws SmppProcessingException { logger.info("new bind request from ip:{} systemId:{}", sessionConfiguration.getHost(), sessionConfiguration.getSystemId()); checkIfConnectionFromIpIsOverLimit(sessionConfiguration.getHost()); - SmppSessionContext context = authProvider.authenticate( + var context = authProvider.authenticate( sessionConfiguration.getSystemId(), sessionConfiguration.getPassword(), sessionConfiguration.getHost() ); - pendingSessionContexts.put(sessionId, context); String accountId = context.getAccountId(); checkIfConnectionsFromAccountIdIsOverLimit(accountId, context.getMaxConnections()); @@ -63,6 +62,7 @@ public void sessionBindRequested( String packageName = SmppServerBindHandler.class.getPackageName(); sessionConfiguration.getLoggingOptions().setLoggerName(packageName); sessionConfiguration.getLoggingOptions().setLogParamPrefix("accId:" + accountId); + pendingSessionContexts.put(sessionId, context); } public void sessionCreated( @@ -73,7 +73,7 @@ public void sessionCreated( String accountId = session.getConfiguration().getName(); Tlv optional = new Tlv(SmppConstants.TAG_SC_INTERFACE_VERSION, new byte[]{SmppConstants.VERSION_3_4}, "Interface Version"); preparedBindResponse.setOptionalParameter(optional); - SmppSessionContext smppSessionContext = pendingSessionContexts.remove(sessionId); + var smppSessionContext = pendingSessionContexts.remove(sessionId); var handler = new SmppServerSessionHandler(worker, sessionId, session, smppSessionContext, submitSmProcessor); if (smppSessionContext != null && !Strings.isNullOrEmpty(smppSessionContext.getProduct())) { handler.setApiProduct(smppSessionContext.getProduct()); @@ -129,6 +129,7 @@ public void sessionDestroyed(Long sessionId, SmppServerSession session) { logger.info("final session rx-submitSM: name:{}-{}", session.getConfiguration().getName(), session.getCounters().getRxSubmitSM()); } connections.removeConnection(session); + pendingSessionContexts.remove(sessionId); session.destroy(); }