private void verifyToActivate(String clientID, ClientSession targetSession) { if (m_clientIDs.containsKey(clientID)) { targetSession.activate(); } }
public void processConnect(ServerChannel session, ConnectMessage msg) { LOG.debug("CONNECT for client <{}>", msg.getClientID()); if (msg.getProtocolVersion() != VERSION_3_1 && msg.getProtocolVersion() != VERSION_3_1_1) { ConnAckMessage badProto = new ConnAckMessage(); badProto.setReturnCode(ConnAckMessage.UNNACEPTABLE_PROTOCOL_VERSION); LOG.warn("processConnect sent bad proto ConnAck"); session.write(badProto); session.close(false); return; } if (msg.getClientID() == null || msg.getClientID().length() == 0) { ConnAckMessage okResp = new ConnAckMessage(); okResp.setReturnCode(ConnAckMessage.IDENTIFIER_REJECTED); session.write(okResp); m_interceptor.notifyClientConnected(msg); return; } // handle user authentication if (msg.isUserFlag()) { byte[] pwd = null; if (msg.isPasswordFlag()) { pwd = msg.getPassword(); } else if (!this.allowAnonymous) { failedCredentials(session); return; } if (!m_authenticator.checkValid(msg.getUsername(), pwd)) { failedCredentials(session); return; } session.setAttribute(NettyChannel.ATTR_KEY_USERNAME, msg.getUsername()); } else if (!this.allowAnonymous) { failedCredentials(session); return; } // if an old client with the same ID already exists close its session. if (m_clientIDs.containsKey(msg.getClientID())) { LOG.info( "Found an existing connection with same client ID <{}>, forcing to close", msg.getClientID()); // clean the subscriptions if the old used a cleanSession = true ServerChannel oldSession = m_clientIDs.get(msg.getClientID()).session; ClientSession oldClientSession = m_sessionsStore.sessionForClient(msg.getClientID()); oldClientSession.disconnect(); oldSession.setAttribute(NettyChannel.ATTR_KEY_SESSION_STOLEN, true); oldSession.close(false); LOG.debug("Existing connection with same client ID <{}>, forced to close", msg.getClientID()); } ConnectionDescriptor connDescr = new ConnectionDescriptor(msg.getClientID(), session, msg.isCleanSession()); m_clientIDs.put(msg.getClientID(), connDescr); int keepAlive = msg.getKeepAlive(); LOG.debug("Connect with keepAlive {} s", keepAlive); session.setAttribute(NettyChannel.ATTR_KEY_KEEPALIVE, keepAlive); session.setAttribute(NettyChannel.ATTR_KEY_CLEANSESSION, msg.isCleanSession()); // used to track the client in the subscription and publishing phases. session.setAttribute(NettyChannel.ATTR_KEY_CLIENTID, msg.getClientID()); LOG.debug("Connect create session <{}>", session); session.setIdleTime(Math.round(keepAlive * 1.5f)); // Handle will flag if (msg.isWillFlag()) { AbstractMessage.QOSType willQos = AbstractMessage.QOSType.valueOf(msg.getWillQos()); byte[] willPayload = msg.getWillMessage(); ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(willPayload.length).put(willPayload).flip(); // save the will testament in the clientID store WillMessage will = new WillMessage(msg.getWillTopic(), bb, msg.isWillRetain(), willQos); m_willStore.put(msg.getClientID(), will); } ConnAckMessage okResp = new ConnAckMessage(); okResp.setReturnCode(ConnAckMessage.CONNECTION_ACCEPTED); ClientSession clientSession = m_sessionsStore.sessionForClient(msg.getClientID()); boolean isSessionAlreadyStored = clientSession != null; if (!msg.isCleanSession() && isSessionAlreadyStored) { okResp.setSessionPresent(true); } session.write(okResp); m_interceptor.notifyClientConnected(msg); if (!isSessionAlreadyStored) { LOG.info("Create persistent session for clientID <{}>", msg.getClientID()); clientSession = m_sessionsStore.createNewSession(msg.getClientID(), msg.isCleanSession()); } clientSession.activate(); if (msg.isCleanSession()) { clientSession.cleanSession(); } LOG.info( "Connected client ID <{}> with clean session {}", msg.getClientID(), msg.isCleanSession()); if (!msg.isCleanSession()) { // force the republish of stored QoS1 and QoS2 republishStoredInSession(clientSession); } LOG.info("CONNECT processed"); }