Details

    • Type: New Feature
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 5
    • Fix Version/s: None
    • Component/s: core
    • Labels:
      None

      Description

      This was discussed in MQTT-276 with notes from the F2F meetings and has been tracked in MQTT-256.

      I'm opening a separate, specific issue per Ken's comments - https://issues.oasis-open.org/browse/MQTT-256?focusedCommentId=62192&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-62192:

      "All of these would be defined in separate JIRAs, but what we should do in this JIRA is to define the mechanism used to pass these values."

        Attachments

          Activity

          Hide
          edbriggs Ed Briggs [X] (Inactive) added a comment -

          This note describes the mechanism used by a Server to notify a Client it does not support RETAIN messages, and related actions to be taken by the Client and Server. It works by the server 'advertising' that it does not support RETAIN by including a tag in the CONNACK. To reduce message overhead for the common case, the tag is only present if RETAIN is not supported.

          The idea is simple, but the implementation is somewhat complicated by:

          a) WD04 Section 3.2.2.3 "Connect Return Codes" BREAKS this feature with the following non-normative text
          "The Server may choose to close the network connection without sending a CONNACK to enhance security
          in the case where an error is found in the CONNECT..." . This requires discussion/clarification of the WD text.

          b) the CONNECT message can carry a RETAIN flag (for the Will message) making an advertisement in a CONNACK 'to late' to be useful.

          c) A Client may send PUBLISH commands with RETAIN=1 prior to receiving a CONNACK containing notification that RETAIN is not supported. Again, the advertisement arrives too late.

          d) Using transport disconnection or DISCONNECT commands in response to violation of the RETAIN advertisement on QoS > 0 may result in infinite re-connect/retry cycles.

          e) QoS 0 has no ACK/NAK so DISCONNECT must be used to respond to violation of the RETAIN-NOT-SUPPORTED advertisement by QoS 0 PUBLISH commands.Introduction

          NOTE 1 - This JIRA is a work item taken from the original 'METADATA' JIRA These items have been broken into separate JIRAs to divide and (hopefully) conquer them.

          NOTE 2 - This proposes new behavior not yet reviewed by the TC. Please review and comment.

          NOTE 3 - This proposes two new Error Codes to be added
          a) DISCONNECT reason RETAIN-NOT-SUPPORTED
          b) PUBACK RETAIN-NOT-SUPPORTED

          NOTE 4 - The encoding of the RETAIN-NOT-SUPPORTED advertisement follows WD04 Section 2.3.3 "Identifier/Value Pairs" which specifies a single byte identifier followed by a length field.

          {This section to be added in the CONNACK payload description}

          Retain Unavailable Advertisement
          --------------------------------

          Identifier value 34 (0x22) followed by a zero length payload signifies that a Server will reject messages in which the RETAIN flag is set to 1.

          A Server which does not implement the RETAIN message capability MUST send a CONNACK containing a RETAIN UNAVAILABLE Advertisement in response to a CONNECT message. It is an error to include the RETAIN UNAVAILABLE message more than once. If the Server rejects the CONNECT for any other reason, it MUST NOT send a RETAIN UNAVAILABLE advertisement.

          A Server providing RETAIN message capabilities MUST NOT send the RETAIN UNAVAILABLE Advertisement.

          {This text to be added to the section on RETAIN}

          If a server does not support RETAIN, and it receives a CONNECT message with a WILL RETAIN flag set in the Connect Flags Field, it MUST reject the CONNECT command and send a CONNACK with a return code of RETAIN NOT SUPPORTED and then close the transport connection.

          A Client which has received CONNACK with a RETAIN UNAVAILABLE Advertisement MUST NOT send PUBLISH commands with RETAIN=1 in the fixed header.

          If a Server does not support RETAIN, and it receives QoS 0 PUBLISH commands marked with a RETAIN = 1 in the PUBLISH Fixed Header, it MUST transmit a DISCONNECT message with a return code RETAIN-NOT-SUPPORTED and then disconnect the transport connection. This behavior is also used if a Client sends QoS 0 PUBLISH commands before a CONNACK.

          If a Server does not support RETAIN, and it receives a QoS 1 or QoS 2 PUBLISH command, it MUST respond with PUBACK or PUBREC with a return code of RETAIN-NOT-SUPPORTED. It MUST NOT close the session or transport connection because doing so could result in cyclical retries. This behavior is also used if a Client sends QoS > 0 PUBLISH commands before a CONNACK.

          Show
          edbriggs Ed Briggs [X] (Inactive) added a comment - This note describes the mechanism used by a Server to notify a Client it does not support RETAIN messages, and related actions to be taken by the Client and Server. It works by the server 'advertising' that it does not support RETAIN by including a tag in the CONNACK. To reduce message overhead for the common case, the tag is only present if RETAIN is not supported. The idea is simple, but the implementation is somewhat complicated by: a) WD04 Section 3.2.2.3 "Connect Return Codes" BREAKS this feature with the following non-normative text "The Server may choose to close the network connection without sending a CONNACK to enhance security in the case where an error is found in the CONNECT..." . This requires discussion/clarification of the WD text. b) the CONNECT message can carry a RETAIN flag (for the Will message) making an advertisement in a CONNACK 'to late' to be useful. c) A Client may send PUBLISH commands with RETAIN=1 prior to receiving a CONNACK containing notification that RETAIN is not supported. Again, the advertisement arrives too late. d) Using transport disconnection or DISCONNECT commands in response to violation of the RETAIN advertisement on QoS > 0 may result in infinite re-connect/retry cycles. e) QoS 0 has no ACK/NAK so DISCONNECT must be used to respond to violation of the RETAIN-NOT-SUPPORTED advertisement by QoS 0 PUBLISH commands.Introduction NOTE 1 - This JIRA is a work item taken from the original 'METADATA' JIRA These items have been broken into separate JIRAs to divide and (hopefully) conquer them. NOTE 2 - This proposes new behavior not yet reviewed by the TC. Please review and comment. NOTE 3 - This proposes two new Error Codes to be added a) DISCONNECT reason RETAIN-NOT-SUPPORTED b) PUBACK RETAIN-NOT-SUPPORTED NOTE 4 - The encoding of the RETAIN-NOT-SUPPORTED advertisement follows WD04 Section 2.3.3 "Identifier/Value Pairs" which specifies a single byte identifier followed by a length field. {This section to be added in the CONNACK payload description} Retain Unavailable Advertisement -------------------------------- Identifier value 34 (0x22) followed by a zero length payload signifies that a Server will reject messages in which the RETAIN flag is set to 1. A Server which does not implement the RETAIN message capability MUST send a CONNACK containing a RETAIN UNAVAILABLE Advertisement in response to a CONNECT message. It is an error to include the RETAIN UNAVAILABLE message more than once. If the Server rejects the CONNECT for any other reason, it MUST NOT send a RETAIN UNAVAILABLE advertisement. A Server providing RETAIN message capabilities MUST NOT send the RETAIN UNAVAILABLE Advertisement. {This text to be added to the section on RETAIN} If a server does not support RETAIN, and it receives a CONNECT message with a WILL RETAIN flag set in the Connect Flags Field, it MUST reject the CONNECT command and send a CONNACK with a return code of RETAIN NOT SUPPORTED and then close the transport connection. A Client which has received CONNACK with a RETAIN UNAVAILABLE Advertisement MUST NOT send PUBLISH commands with RETAIN=1 in the fixed header. If a Server does not support RETAIN, and it receives QoS 0 PUBLISH commands marked with a RETAIN = 1 in the PUBLISH Fixed Header, it MUST transmit a DISCONNECT message with a return code RETAIN-NOT-SUPPORTED and then disconnect the transport connection. This behavior is also used if a Client sends QoS 0 PUBLISH commands before a CONNACK. If a Server does not support RETAIN, and it receives a QoS 1 or QoS 2 PUBLISH command, it MUST respond with PUBACK or PUBREC with a return code of RETAIN-NOT-SUPPORTED. It MUST NOT close the session or transport connection because doing so could result in cyclical retries. This behavior is also used if a Client sends QoS > 0 PUBLISH commands before a CONNACK.
          Hide
          ken.borgendale Ken Borgendale (Inactive) added a comment -

          As to the publish before the CONNACK, I think we have to say generally that a client which proceeds to publish before receiving the CONNACK is assuming that it knows what the response to the CONNACK will be. Obviously it could be wrong, and in such as case it most likely will not retry as it most likely just closed the connection without waiting for any response.

          The text about CONNACK (and indeed DISCONNECT) being optional before closing the connection is a clear statement that the Client or Server are free to close the connection at any point and for any reason without informing the other side. Indeed the network between the two may do this as well. To avoid problems it is commonly good to inform the other side, but doing so may in some cases be impossible, and in other cases allow a security exploit. Even if the Sever sends a CONNACK or DISCONNECT before closing the connection, it is not guaranteed that the Client can receive it before it seeing the connection close.

          I would prefer to say that a Server which sent the Retain Unavailable could optionally simply not honor the retain bit. This is especially useful for the QoS=0 or will message case.

          If the Sever supports retain in some cases but not in others, for some topics, or if a short enough message expiration is used or not for some QoS then I presume it should not send the Retain Unavailable. Is is still allowed to use the Retain not supported return code when it rejects a PUBLISH with the retain set?

          What is the reason for saying: "If the Server rejects the CONNECT for any other reason, it MUST NOT send a RETAIN UNAVAILABLE advertisement"? I assume this means that the Retain Unavailable may only be sent for a CONNACK with a return code of less than 128. We have not stated this for other CONNACK id/value pairs.

          Again I strong disagree with the statement that the Server MUST NOT close the session based on getting retain on QoS>0. I again assert that the Server is allowed to close the connection for any reason at any time. How would you test such an imperative?

          Show
          ken.borgendale Ken Borgendale (Inactive) added a comment - As to the publish before the CONNACK, I think we have to say generally that a client which proceeds to publish before receiving the CONNACK is assuming that it knows what the response to the CONNACK will be. Obviously it could be wrong, and in such as case it most likely will not retry as it most likely just closed the connection without waiting for any response. The text about CONNACK (and indeed DISCONNECT) being optional before closing the connection is a clear statement that the Client or Server are free to close the connection at any point and for any reason without informing the other side. Indeed the network between the two may do this as well. To avoid problems it is commonly good to inform the other side, but doing so may in some cases be impossible, and in other cases allow a security exploit. Even if the Sever sends a CONNACK or DISCONNECT before closing the connection, it is not guaranteed that the Client can receive it before it seeing the connection close. I would prefer to say that a Server which sent the Retain Unavailable could optionally simply not honor the retain bit. This is especially useful for the QoS=0 or will message case. If the Sever supports retain in some cases but not in others, for some topics, or if a short enough message expiration is used or not for some QoS then I presume it should not send the Retain Unavailable. Is is still allowed to use the Retain not supported return code when it rejects a PUBLISH with the retain set? What is the reason for saying: "If the Server rejects the CONNECT for any other reason, it MUST NOT send a RETAIN UNAVAILABLE advertisement"? I assume this means that the Retain Unavailable may only be sent for a CONNACK with a return code of less than 128. We have not stated this for other CONNACK id/value pairs. Again I strong disagree with the statement that the Server MUST NOT close the session based on getting retain on QoS>0. I again assert that the Server is allowed to close the connection for any reason at any time. How would you test such an imperative?
          Hide
          edbriggs Ed Briggs [X] (Inactive) added a comment -

          Ken,
          If a server can simply ignore the RETAIN flag in the CONNECT and PUBLISH messages that arrive before it sends a CONNACK, and it can also ignore RETAIN after sending a CONNACK with a RETAIN Unavailable advertisement on some, but not necessarily all messages, should we just say that implementing RETAIN is not a mandatory requirement for compliance with MQTT 5.0? I'm not trying to be flippant here, I am having difficulty imagining how to specify this kind of 'maybe sometimes' or 'client has to guess' behavior in normative text.

          Show
          edbriggs Ed Briggs [X] (Inactive) added a comment - Ken, If a server can simply ignore the RETAIN flag in the CONNECT and PUBLISH messages that arrive before it sends a CONNACK, and it can also ignore RETAIN after sending a CONNACK with a RETAIN Unavailable advertisement on some, but not necessarily all messages, should we just say that implementing RETAIN is not a mandatory requirement for compliance with MQTT 5.0? I'm not trying to be flippant here, I am having difficulty imagining how to specify this kind of 'maybe sometimes' or 'client has to guess' behavior in normative text.
          Hide
          edbriggs Ed Briggs [X] (Inactive) added a comment -

          I propose the following behavior for the RETAIN unavailable advertisement and processing.

          1. If a Server support Retain, it MUST NOT send a RETAIN UNAVAILABLE in the CONNACK.
          2. If a Server does not wish to support RETAIN, it MUST send a RETAIN UNAVAILABLE advertisement on the CONNACK if a CONNACK is sent.
          3. If a Server does not wish to support RETAIN, and it receives a CONNECT with a Will RETAIL indication, it ignores the RETAIN but processes the CONNECT normally and returns the appropriate return code in the CONNACK with a RETAIN UNAVAILABLE advertisement.
          4. If a Server does not wish to support RETAIN and receives a PUBLISH with a RETAIN flag set, it simply ignores the RETAIN flag and processes the PUBLISH normally.

          Notes:
          1. The Error code 'retain not supported' will be removed from the standard

          2. The behavior has the effect of making RETAIN an optional feature for a Server. The notifies the Client if RETAIN support is absent. It is the Client Application responsibility
          to check for the Retain Unavailable advertisement, and decide what if any action it might take.

          Show
          edbriggs Ed Briggs [X] (Inactive) added a comment - I propose the following behavior for the RETAIN unavailable advertisement and processing. 1. If a Server support Retain, it MUST NOT send a RETAIN UNAVAILABLE in the CONNACK. 2. If a Server does not wish to support RETAIN, it MUST send a RETAIN UNAVAILABLE advertisement on the CONNACK if a CONNACK is sent. 3. If a Server does not wish to support RETAIN, and it receives a CONNECT with a Will RETAIL indication, it ignores the RETAIN but processes the CONNECT normally and returns the appropriate return code in the CONNACK with a RETAIN UNAVAILABLE advertisement. 4. If a Server does not wish to support RETAIN and receives a PUBLISH with a RETAIN flag set, it simply ignores the RETAIN flag and processes the PUBLISH normally. Notes: 1. The Error code 'retain not supported' will be removed from the standard 2. The behavior has the effect of making RETAIN an optional feature for a Server. The notifies the Client if RETAIN support is absent. It is the Client Application responsibility to check for the Retain Unavailable advertisement, and decide what if any action it might take.
          Hide
          edbriggs Ed Briggs [X] (Inactive) added a comment -

          I request this simplified behavior be accepted by the TC so it can be assigned to the editors.

          Show
          edbriggs Ed Briggs [X] (Inactive) added a comment - I request this simplified behavior be accepted by the TC so it can be assigned to the editors.
          Hide
          ken.borgendale Ken Borgendale (Inactive) added a comment -

          Issue included in MQTTv5.0 CS01 December 25, 2017

          Show
          ken.borgendale Ken Borgendale (Inactive) added a comment - Issue included in MQTTv5.0 CS01 December 25, 2017

            People

            • Assignee:
              edbriggs Ed Briggs [X] (Inactive)
              Reporter:
              brianraymor Brian Raymor [X] (Inactive)
            • Watchers:
              3 Start watching this issue

              Dates

              • Due:
                Created:
                Updated:
                Resolved: