From 6c77fa1bf7fe46683d4a5169fb184c602a1dc0fe Mon Sep 17 00:00:00 2001 From: Zaiming Shi Date: Thu, 25 Mar 2021 15:11:03 +0100 Subject: [PATCH] fix(emqx_channel): Receive Maximum spec compliance According to MQTT 5.0 specification If the Receive Maximum value is absent then its value defaults to 65,535. --- include/emqx_mqtt.hrl | 3 +-- priv/emqx.schema | 2 +- src/emqx_channel.erl | 12 +++++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/emqx_mqtt.hrl b/include/emqx_mqtt.hrl index c38a167da..220fbbb1c 100644 --- a/include/emqx_mqtt.hrl +++ b/include/emqx_mqtt.hrl @@ -181,8 +181,7 @@ -define(MAX_PACKET_ID, 16#FFFF). -define(MAX_PACKET_SIZE, 16#FFFFFFF). -define(MAX_TOPIC_AlIAS, 16#FFFF). - --define(MAX_INFLIGHT_HARD_LIMIT, 32767). +-define(RECEIVE_MAXIMUM_LIMIT, ?MAX_PACKET_ID). %%-------------------------------------------------------------------- %% MQTT Frame Mask diff --git a/priv/emqx.schema b/priv/emqx.schema index 131a4dd82..9bb8a5019 100644 --- a/priv/emqx.schema +++ b/priv/emqx.schema @@ -937,7 +937,7 @@ end}. {mapping, "zone.$name.max_inflight", "emqx.zones", [ {default, 0}, {datatype, integer}, - {validators, ["range:1-32767"]} + {validators, ["range:1-65535"]} ]}. %% @doc Retry interval for redelivering QoS1/2 messages. diff --git a/src/emqx_channel.erl b/src/emqx_channel.erl index ef9a83315..6e44e0a22 100644 --- a/src/emqx_channel.erl +++ b/src/emqx_channel.erl @@ -1119,7 +1119,6 @@ enrich_conninfo(ConnPkt = #mqtt_packet_connect{ clientinfo = #{zone := Zone} }) -> ExpiryInterval = expiry_interval(Zone, ConnPkt), - ReceiveMaximum = receive_maximum(Zone, ConnProps), NConnInfo = ConnInfo#{proto_name => ProtoName, proto_ver => ProtoVer, clean_start => CleanStart, @@ -1128,7 +1127,7 @@ enrich_conninfo(ConnPkt = #mqtt_packet_connect{ username => Username, conn_props => ConnProps, expiry_interval => ExpiryInterval, - receive_maximum => ReceiveMaximum + receive_maximum => receive_maximum(Zone, ConnProps) }, {ok, Channel#channel{conninfo = NConnInfo}}. @@ -1144,11 +1143,14 @@ expiry_interval(_Zone, #mqtt_packet_connect{clean_start = true}) -> receive_maximum(Zone, ConnProps) -> MaxInflightConfig = case emqx_zone:max_inflight(Zone) of - 0 -> ?MAX_INFLIGHT_HARD_LIMIT; + 0 -> ?RECEIVE_MAXIMUM_LIMIT; N -> N end, - MaxByClient = emqx_mqtt_props:get('Receive-Maximum', ConnProps, MaxInflightConfig), - erlang:min(MaxByClient, MaxInflightConfig). + %% Received might be zero which should be a protocol error + %% we do not validate MQTT properties here + %% it is to be caught later + Received = emqx_mqtt_props:get('Receive-Maximum', ConnProps, MaxInflightConfig), + erlang:min(Received, MaxInflightConfig). %%-------------------------------------------------------------------- %% Run Connect Hooks