oasis-tcs / mqtt

OASIS MQTT TC: Technical refinements of features
Other
4 stars 2 forks source link

MQTT-608 Add gateway retransmssion. and clarify client retransmission #14

Closed icraggs closed 3 months ago

icraggs commented 5 months ago

https://issues.oasis-open.org/browse/MQTT-608

The current specification describes the need for client retransmission in section 4.18, however there circumstances where the gateway will also need to retransmit packets.

Discussion points. 1) There is little difference between sending PUBLISH Qos1 NRetry times and then stopping, and sending PUBLISH Qos 0? 2) Once a Qos2 PUBLISH has been sent the receiver may have stored state that it is obliged to keep until it has received PUBREL. MQTT states that in this case the sender MUST NOT apply Publication expiry if a PUBLISH packet has been sent, so that the receivers state is always deleted eventually. MQTT-SN needs to do something similar , so Nretry can't apply to Qos2 messages. 3) Clean start can be used by the Client to reset the protocol Session state if necessary. Session Present can be used by the Gateway to indicate that it has deleted the Session State. The client and Gateway already have a mechanism to close the Virtual Connection and restart with the Session state reset, so that NRetry would not be needed.

4) A retransmitted packet must be identical to the predecessor, otherwise it is ambiguous as to which version is being acknowledged. Is this OK with the Protection Envelope?

icraggs commented 5 months ago

Proposal (Andy):

4.14 Client’s Publish Procedure

At any point in time a client may have only one QoS level 1 or 2 PUBLISH packet outstanding in each direction; i.e. it has to wait for the termination of this PUBLISH packet exchange before it could start a new level 1 or 2 transaction

with...

A Client or Gateway processes a single outbound Qos 1 or Qos 2 message at a time. This prevents retransmitted Qos 1 and Qos 2 messages from being received out of order. A Client MUST NOT send a Qos 1 or Qos 2 PUBLISH packet with a new Application Message until it has received a PUBACK or PUBCOMP Packet with the Packet Identifier corresponding to the PUBLISH packet previously sent. A Gateway MUST NOT send a Qos 1 or Qos 2 PUBLISH packet with a new Application Message until it has received a PUBACK or PUBCOMP Packet with the Packet Identifier corresponding to the PUBLISH packet previously sent.

Replace...

4.18 Client’s Retransmission Procedure All packets that are “unicasted” to the gatewayGW (i.e. sent using the gatewayGW’s unicast address and not broadcasted) and for which a gatewayGW’s reply is expected are supervised by a retry timer Tretry and a retry counter Nretry. The retry timer Tretry is started by the client when the packet is sent and stopped when the expected gatewayGW’s reply is received. If Tretry times out and the expected gatewayGW’s reply is not received, the client retransmits the packet. After Nretry retransmissions, the client aborts the procedure and assumes that the MQTT-SN gateway is no longer available. It should then try to connect to another gateway.

with...

4.18 Retransmission Procedure in the Client and Gateway

The Client or Gateway will start a retransmission retry timer, Tretry, when one of the following Packets is sent.

A Client MUST retransmit CONNECT, AUTH, REGISTER, PUBLISH Qos1, PUBLISH Qos2, PUBREL, SUBSCRIBE, UNSUBSCRIBE Packets, including a PROTECTION envelope if there is one, after Tretry has passed or close the Virtual Connection.

A Gateway MUST retransmit PUBLISH Qos1, PUBLISH Qos2, PUBREL Packets, including a PROTECTION envelope if there is one, after Tretry has passed or close the Virtual Connection.

The timer is cancelled if the corresponding acknowledgement packet is received. The Client or Gateway MUST retransmit the Packet after Tretry has passed or close the Virtual Connection.

If a Packet can be retransmitted it MUST NOT be sent using a Broadcast address.

If a Packet is retransmitted it MUST be identical to the previously transmitted Packet.

PUBLISH (used for QoS 0) and PUBLISH WITHOUT SESSION Packets MUST NOT be retransmitted.

If the Virtual Connection is closed, the protocol will restart when a new CONNECT packet flows from the Client.

Non normative comment.

The value of the retry interval TRetry is not specified by the protocol, however, to be useful it should be longer that the network round trip time. If it is excessively long, the time taken to detect and retransmit lost Packets will also be excessively long. Implementors should take care not to use a retry interval that might cause the network to become congested with retried Packets.

The PINGREQ packet described in {3.1.22 PINGREQ] can also be used to determine whether the virtual connection is alive.

An example of a retry algorithm is described in [???Appendix E.4???]

Reinstate the conformance clauses in ...

3.1.5.3 Connack Flags

If the Gateway accepts a connection with Clean Start set to 1, the Server MUST set Session Present to 0 in the CONNACK packet in addition to setting a 0x00 (Success) Reason Code in the CONNACK packet [????].

If the Gateway accepts a connection with Clean Start set to 0 and the Gateway has Session State for the ClientID, it MUST set Session Present to 1 in the CONNACK packet, otherwise it MUST set Session Present to 0 in the CONNACK packet. In both cases it MUST set a 0x00 (Success) Reason Code in the CONNACK packet [????].

If the value of Session Present received by the Client from the Server is not as expected, the Client proceeds as follows:

· If the Client does not have Session State and receives Session Present set to 1 it MUST close the Virtual Connection [?????]. If it wishes to restart with a new Session the Client can reconnect using Clean Start set to 1.

· If the Client does have Session State and receives Session Present set to 0 it MUST discard its Session State if it continues with the Virtual Connection [????].

If a Server sends a CONNACK packet containing a non-zero Reason Code it MUST set Session Present to 0 [?????].

icraggs commented 5 months ago

Davide Lenzarini [X] (Inactive) added a comment - 15/Feb/24 12:50 PM - edited

"A Client MUST NOT send a Qos 1 or Qos 2 PUBLISH packet with a new Application Message until it has received a PUBACK or PUBCOMP Packet with the corresponding Packet Identifier."

"A Gateway MUST NOT send a Qos 1 or Qos 2 PUBLISH packet with a new Application Message until it has received a PUBACK or PUBCOMP Packet with the corresponding Packet Identifier."

Andrew Banks [X] I would propose the following changes

"A Client MUST NOT send a new Qos 1 or Qos 2 PUBLISH packet with a new Application Message until it has received a PUBACK or PUBCOMP Packet with the corresponding Packet Identifier of the one previously sent to the same Gateway."
"A Gateway MUST NOT send a new Qos 1 or Qos 2 PUBLISH packet with a new Application Message until it has received a PUBACK or PUBCOMP Packet with the corresponding Packet Identifier of the one previously sent to the same Client."

davide.lenzarini Davide Lenzarini [X] (Inactive) added a comment - 15/Feb/24 12:57 PM - edited

"A Client MUST retransmit CONNECT, AUTH, REGISTER, PUBLISH Qos1, PUBLISH Qos2, PUBREL, SUBSCRIBE, UNSUBSCRIBE, WILLTOPICUPD, WILLMSGUPD Packets after Tretry has passed or close the Virtual Connection."

"A Gateway MUST retransmit WILLTOPICREQ, WILLMSGREQ, PUBLISH Qos1, PUBLISH Qos2, PUBREL Packets after Tretry has passed or close the Virtual Connection."

Andrew Banks [X]I would propose the following changes

"A Client MUST retransmit CONNECT, AUTH, REGISTER, PUBLISH Qos1, PUBLISH Qos2, PUBREL, SUBSCRIBE, UNSUBSCRIBE-, WILLTOPICUPD, WILLMSGUPD- Packets and the PROTECTION packet, if wrapping one of them, after Tretry has passed or close the Virtual Connection."

"A Gateway MUST retransmit WILLTOPICREQ, WILLMSGREQ, PUBLISH Qos1, PUBLISH Qos2, PUBREL Packets and the PROTECTION packet, if wrapping one of them, after Tretry has passed or close the Virtual Connection."

sdrees Stefan Drees (Inactive) added a comment - 06/Mar/24 4:30 PM - edited

I think any POUBLISH should become PUBLISH.

sdrees Stefan Drees (Inactive) added a comment - 06/Mar/24 4:37 PM - edited

Suggest to replace:

The value of the retry interval TRetry is not specified by the protocol, however, to be useful it should be longer that the network round trip time. If it is excessively long, the time taken to detect and retransmit lost Packets will also be excessively long. Implementors should take care not to use a retry interval that might cause the network to become congested with retried Packets.

With (note that -> than (fix) and twice should -> better (style option, as we are in an informative section only; but there are for sure better choices ...)):

The value of the retry interval TRetry is not specified by the protocol, however, to be useful it better be longer than the network round trip time. If it is excessively long, the time taken to detect and retransmit lost Packets will also be excessively long. Implementors better take care not to use a retry interval that might cause the network to become congested with retried Packets.

sdrees Stefan Drees (Inactive) added a comment - 06/Mar/24 4:40 PM - edited

Suggest to replace:

If a Packet can be retransmitted it MUST NOT be sent using a Broadcast address.

with (avoid MUST NOT and state what MUST - assuming Multicast would also not be helpful ...):

If a Packet can be retransmitted it MUST be sent using a Unicast address.

or even (because "if ... can MUST" to me provokes the question when this is the case where it should highlight the MUST part):

Any Packet retransmission MUST be using a Unicast address.
icraggs commented 3 months ago

Tracking in Jira again.

sthagen commented 2 months ago

At https://issues.oasis-open.org/browse/MQTT-608