List of usage examples for io.netty.handler.codec.mqtt MqttConnectReturnCode CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION
MqttConnectReturnCode CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION
To view the source code for io.netty.handler.codec.mqtt MqttConnectReturnCode CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION.
Click Source Link
From source file:com.caricah.iotracah.core.handlers.ConnectionHandler.java
License:Apache License
/** * * 3.1.4 Response//from w w w .jav a2 s . c om * <p> * Note that a Server MAY support multiple protocols (including earlier versions of this protocol) * on the same TCP port or other network endpoint. If the Server determines that the protocol is MQTT 3.1.1 * then it validates the connection attempt as follows. * <p> * 1. If the Server does not receive a CONNECT Packet within a reasonable amount of time after * the Network Connection is established, the Server SHOULD close the connection. * <p> * 2. The Server MUST validate that the CONNECT Packet conforms to section 3.1 and close * the Network Connection without sending a CONNACK if it does not conform [MQTT-3.1.4-1]. * <p> * 3. The Server MAY check that the contents of the CONNECT Packet meet any further restrictions * and MAY perform authentication and authorization checks. If any of these checks fail, * it SHOULD send an appropriate CONNACK response with a non-zero return code as described * in section 3.2 and it MUST close the Network Connection. * <p> * If validation is successful the Server performs the following steps. * <p> * 1. If the ClientId represents a Client already connected to the Server then * the Server MUST disconnect the existing Client [MQTT-3.1.4-2]. * 2. The Server MUST perform the processing of CleanSession that is described * in section 3.1.2.4 [MQTT-3.1.4-3]. * 3. The Server MUST acknowledge the CONNECT Packet with a CONNACK Packet * containing a zero return code [MQTT-3.1.4-4]. * 4. Start message delivery and keep alive monitoring. * <p> * Clients are allowed to send further Control Packets immediately after sending a CONNECT Packet; * Clients need not wait for a CONNACK Packet to arrive from the Server. If the Server rejects the CONNECT, * it MUST NOT process any data sent by the Client after the CONNECT Packet [MQTT-3.1.4-5]. * <p> * Non normative comment * Clients typically wait for a CONNACK Packet, * However, if the Client exploits its freedom to send Control Packets before it receives a CONNACK, * it might simplify the Client implementation as it does not have to police the connected state. * The Client accepts that any data that it sends before it receives a CONNACK packet from the * Server will not be processed if the Server rejects the connection. * * @return * @throws RetriableException * @throws UnRetriableException */ @Override public void handle(ConnectMessage connectMessage) throws RetriableException, UnRetriableException { log.debug(" handle : client initiating a new connection."); /** * 2. The Server MUST validate that the CONNECT Packet conforms to section 3.1 and close * the Network Connection without sending a CONNACK if it does not conform [MQTT-3.1.4-1]. * * 3.1[ The Server MUST process a second CONNECT Packet sent from a Client as a protocol * violation and disconnect the Client [MQTT-3.1.0-2]. See section 4.8 for information about handling errors.] * * */ try { if (!MqttVersion.MQTT_3_1_1.protocolName().equals(connectMessage.getProtocolName()) && !MqttVersion.MQTT_3_1.protocolName().equals(connectMessage.getProtocolName())) { /** * If the protocol name is incorrect the Server MAY disconnect the Client, * or it MAY continue processing the CONNECT packet in accordance with some other specification. * In the latter case, the Server MUST NOT continue to process the CONNECT packet in line with * this specification [MQTT-3.1.2-1]. * */ throw new UnknownProtocalException(); } if (MqttVersion.MQTT_3_1_1.protocolLevel() != connectMessage.getProtocalLevel() && MqttVersion.MQTT_3_1.protocolLevel() != connectMessage.getProtocalLevel()) { /** * The 8 bit unsigned value that represents the revision level of the protocol used by the Client. * The value of the Protocol Level field for the version 3.1.1 of the protocol is 4 (0x04). * The Server MUST respond to the CONNECT Packet with a CONNACK return code 0x01 (unacceptable protocol level) * and then disconnect the Client if the Protocol Level is not supported by the Server [MQTT-3.1.2-2]. */ throw new MqttUnacceptableProtocolVersionException(); } else { log.debug(" handle: the required protocal was selected."); } //TODO: The Server MUST validate that the reserved flag in the CONNECT Control Packet is set to zero and disconnect the Client if it is not zero [MQTT-3.1.2-3]. //We now proceed to openning a session on our core service interface. boolean cleanSession = connectMessage.isCleanSession(); /** * The Server MUST allow ClientIds which are between 1 and 23 UTF-8 encoded bytes in length, * and that contain only the characters * "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" [MQTT-3.1.3-5]. * * The Server MAY allow ClientIds that contain more than 23 encoded bytes. * The Server MAY allow ClientIds that contain characters not included in the list given above. * * * A Server MAY allow a Client to supply a ClientId that has a length of zero bytes, * however if it does so the Server MUST treat this as a special case and assign a unique ClientId to that Client. * It MUST then process the CONNECT packet as if the Client had provided that unique ClientId [MQTT-3.1.3-6]. * */ String clientIdentifier = connectMessage.getClientId(); /** * If the Client supplies a zero-byte ClientId, the Client MUST also set CleanSession to 1 [MQTT-3.1.3-7]. * * If the Client supplies a zero-byte ClientId with CleanSession set to 0, * the Server MUST respond to the CONNECT Packet with a CONNACK return code 0x02 (Identifier rejected) * and then close the Network Connection [MQTT-3.1.3-8]. */ if ((null == clientIdentifier || clientIdentifier.isEmpty())) { if (!cleanSession) { throw new MqttIdentifierRejectedException(); } } else { //Run a regular expression to check for invalid characters in our clientIdentifier. if (!pattern.matcher(clientIdentifier).matches()) { throw new MqttIdentifierRejectedException(); } } log.debug(" handle: we are ready now to obtain the core session."); Observable<IOTClient> newClientObservable = openSubject(connectMessage.getCluster(), connectMessage.getNodeId(), connectMessage.getConnectionId(), clientIdentifier, cleanSession, connectMessage.getUserName(), connectMessage.getPassword(), connectMessage.getKeepAliveTime(), connectMessage.getSourceHost(), connectMessage.getProtocol()); newClientObservable.subscribe( (iotSession) -> { log.debug(" handle: obtained a client session : {}. ", iotSession); /** * 3. The Server MAY check that the contents of the CONNECT Packet meet any further restrictions * and MAY perform authentication and authorization checks. If any of these checks fail, * it SHOULD send an appropriate CONNACK response with a non-zero return code as described * in section 3.2 and it MUST close the Network Connection. * */ //Respond to server with a connection successfull. ConnectAcknowledgeMessage connectAcknowledgeMessage = ConnectAcknowledgeMessage.from( connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_ACCEPTED); connectAcknowledgeMessage = iotSession.copyTransmissionData(connectAcknowledgeMessage); connectAcknowledgeMessage.setAuthKey(iotSession.getAuthKey()); pushToServer(connectAcknowledgeMessage); if (connectMessage.isHasWill()) { /** * If the Will Flag is set to 1 this indicates that, if the Connect request is accepted, * a Will Message MUST be stored on the Server and associated with the Network Connection. * The Will Message MUST be published when the Network Connection is subsequently closed unless * the Will Message has been deleted by the Server on receipt of a DISCONNECT Packet [MQTT-3.1.2-8]. */ PublishMessage publishMessage = PublishMessage.from(PublishMessage.ID_TO_SHOW_IS_WILL, false, connectMessage.getWillQos(), false, connectMessage.getWillTopic(), ByteBuffer.wrap(connectMessage.getWillMessage().getBytes()), false); publishMessage.setClientId(iotSession.getSessionId()); publishMessage.setSessionId(iotSession.getSessionId()); publishMessage.setPartitionId(iotSession.getPartitionId()); // We have the appropriate id's to save the will. getDatastore().saveWill(iotSession, publishMessage); log.debug(" handle: message has will : {} ", publishMessage); } else { //We need to clear the existing will if any. getDatastore().removeWill(iotSession); } //Perform a reset for our session. getWorker().getSessionResetManager().process(iotSession); }, (e) -> { log.error(" onError : Problems ", e); ConnectAcknowledgeMessage connectAcknowledgeMessage; if (e instanceof AuthenticationException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD); } else if (e instanceof AuthorizationException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED); } else { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); } connectAcknowledgeMessage.copyTransmissionData(connectMessage); pushToServer(connectAcknowledgeMessage); }, () -> { }); } catch (MqttUnacceptableProtocolVersionException | MqttIdentifierRejectedException | AuthenticationException | UnknownProtocalException e) { log.debug(" handle : Client connection issues ", e); //Respond to server with a connection unsuccessfull. ConnectAcknowledgeMessage connectAcknowledgeMessage; if (e instanceof MqttIdentifierRejectedException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_IDENTIFIER_REJECTED); } else if (e instanceof MqttUnacceptableProtocolVersionException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION); } else if (e instanceof UnknownProtocalException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION); } else { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); } connectAcknowledgeMessage.copyTransmissionData(connectMessage); throw new ShutdownException(connectAcknowledgeMessage); } catch (Exception systemError) { ConnectAcknowledgeMessage connectAcknowledgeMessage = ConnectAcknowledgeMessage.from( connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); connectAcknowledgeMessage.copyTransmissionData(connectMessage); log.error(" handle : System experienced the error ", systemError); throw new ShutdownException(connectAcknowledgeMessage); } }
From source file:io.crate.mqtt.protocol.MqttProcessor.java
public void handleConnect(Channel channel, MqttConnectMessage msg) { String clientId = msg.payload().clientIdentifier(); LOGGER.debug("CONNECT for client <{}>", clientId); if (!(msg.variableHeader().version() == MqttVersion.MQTT_3_1.protocolLevel() || msg.variableHeader().version() == MqttVersion.MQTT_3_1_1.protocolLevel())) { sendErrorResponse(channel, MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION) .addListener(f -> LOGGER.warn("CONNECT sent UNACCEPTABLE_PROTOCOL_VERSION")); return;//from w w w . j ava 2 s .c o m } // We require the clean session header to be true if client id is not provided // See MQTT-3.1.3-8 http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html if (clientId == null || clientId.length() == 0) { if (msg.variableHeader().isCleanSession() == false) { sendErrorResponse(channel, MqttConnectReturnCode.CONNECTION_REFUSED_IDENTIFIER_REJECTED) .addListener(cf -> LOGGER.warn("CONNECT sent IDENTIFIER_REJECTED")); return; } clientId = UUID.randomUUID().toString(); LOGGER.info("Client connected with server generated identifier: {}", clientId); } NettyUtils.clientID(channel, clientId); int keepAlive = msg.variableHeader().keepAliveTimeSeconds(); if (keepAlive > 0) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Client connected with keepAlive of {} s", keepAlive); } NettyUtils.keepAlive(channel, keepAlive); if (channel.pipeline().names().contains("idleStateHandler")) { channel.pipeline().remove("idleStateHandler"); } // avoid terminating connections too early int allIdleTimeSeconds = Math.round(keepAlive * 1.5f); channel.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, allIdleTimeSeconds)); } channel.writeAndFlush(MqttMessageFactory.newConnAck(MqttConnectReturnCode.CONNECTION_ACCEPTED, true)) .addListener(cf -> LOGGER.info("CONNECT sent CONNECTION_ACCEPTED")); }
From source file:io.crate.mqtt.protocol.MqttProcessorTest.java
@Test public void testConnectWithWrongMqttVersion() throws Exception { EmbeddedChannel ch = new EmbeddedChannel(); MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.CONNECT, false, MqttQoS.AT_LEAST_ONCE, false, 0);/* ww w.j av a2s.c o m*/ MqttConnectVariableHeader variableHeader = new MqttConnectVariableHeader("connect", (byte) 1, false, false, false, (byte) 1, false, false, 60); MqttConnectPayload payload = new MqttConnectPayload("mqttClient", "someTopic", new byte[0], null, null); processor.handleConnect(ch, (MqttConnectMessage) io.netty.handler.codec.mqtt.MqttMessageFactory .newMessage(fixedHeader, variableHeader, payload)); MqttConnAckMessage response = ch.readOutbound(); assertThat(response.variableHeader().connectReturnCode(), is(MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION)); assertFalse(response.variableHeader().isSessionPresent()); }
From source file:io.vertx.mqtt.test.MqttConnectionTest.java
License:Apache License
@Test public void refusedUnacceptableProtocolVersion(TestContext context) { this.expectedReturnCode = MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION; try {/* w ww .j a va 2s .c om*/ MemoryPersistence persistence = new MemoryPersistence(); MqttConnectOptions options = new MqttConnectOptions(); // trying the old 3.1 options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1); MqttClient client = new MqttClient(String.format("tcp://%s:%d", MQTT_SERVER_HOST, MQTT_SERVER_PORT), "12345", persistence); client.connect(options); context.assertTrue(false); } catch (MqttException e) { context.assertTrue(e.getReasonCode() == MqttException.REASON_CODE_INVALID_PROTOCOL_VERSION); e.printStackTrace(); } }
From source file:io.vertx.mqtt.test.MqttConnectionTest.java
License:Apache License
@Override protected void endpointHandler(MqttEndpoint endpoint) { MqttConnectReturnCode returnCode = this.expectedReturnCode; switch (this.expectedReturnCode) { case CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD: returnCode = (endpoint.auth().userName().equals(MQTT_USERNAME) && endpoint.auth().password().equals(MQTT_PASSWORD)) ? MqttConnectReturnCode.CONNECTION_ACCEPTED : MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD; break;/*from ww w . j av a 2 s . c o m*/ case CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION: returnCode = endpoint.protocolVersion() == MqttConnectOptions.MQTT_VERSION_3_1_1 ? MqttConnectReturnCode.CONNECTION_ACCEPTED : MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION; break; } log.info("return code = " + returnCode); if (returnCode == MqttConnectReturnCode.CONNECTION_ACCEPTED) { endpoint.accept(false); } else { endpoint.reject(returnCode); } this.endpoint = endpoint; }
From source file:io.vertx.mqtt.test.server.MqttServerConnectionTest.java
License:Apache License
@Test public void refusedUnacceptableProtocolVersion(TestContext context) { this.expectedReturnCode = MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION; try {/*from w ww . jav a 2s .c o m*/ MemoryPersistence persistence = new MemoryPersistence(); MqttConnectOptions options = new MqttConnectOptions(); // trying the old 3.1 options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1); MqttClient client = new MqttClient(String.format("tcp://%s:%d", MQTT_SERVER_HOST, MQTT_SERVER_PORT), "12345", persistence); client.connect(options); context.fail(); } catch (MqttException e) { context.assertTrue(e.getReasonCode() == MqttException.REASON_CODE_INVALID_PROTOCOL_VERSION); } }
From source file:io.vertx.mqtt.test.server.MqttServerConnectionTest.java
License:Apache License
@Override protected void endpointHandler(MqttEndpoint endpoint) { MqttConnectReturnCode returnCode = this.expectedReturnCode; switch (this.expectedReturnCode) { case CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD: returnCode = (endpoint.auth().userName().equals(MQTT_USERNAME) && endpoint.auth().password().equals(MQTT_PASSWORD)) ? MqttConnectReturnCode.CONNECTION_ACCEPTED : MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD; break;//from w ww .j a va 2 s . co m case CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION: returnCode = endpoint.protocolVersion() == MqttConnectOptions.MQTT_VERSION_3_1_1 ? MqttConnectReturnCode.CONNECTION_ACCEPTED : MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION; break; } log.info("return code = " + returnCode); if (returnCode == MqttConnectReturnCode.CONNECTION_ACCEPTED) { log.info("client id = " + endpoint.clientIdentifier()); endpoint.accept(false); } else { endpoint.reject(returnCode); } this.endpoint = endpoint; }