Pārlūkot izejas kodu

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.
Zaiming Shi 4 gadi atpakaļ
vecāks
revīzija
6c77fa1bf7
3 mainītis faili ar 9 papildinājumiem un 8 dzēšanām
  1. 1 2
      include/emqx_mqtt.hrl
  2. 1 1
      priv/emqx.schema
  3. 7 5
      src/emqx_channel.erl

+ 1 - 2
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

+ 1 - 1
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.

+ 7 - 5
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