diff --git a/apps/emqx/src/emqx_channel.erl b/apps/emqx/src/emqx_channel.erl index 4d6ed37e43..bb9c84e8c1 100644 --- a/apps/emqx/src/emqx_channel.erl +++ b/apps/emqx/src/emqx_channel.erl @@ -2007,14 +2007,15 @@ merge_default_subopts(SubOpts) -> %%-------------------------------------------------------------------- %% Enrich ConnAck Caps -enrich_connack_caps( - AckProps, - ?IS_MQTT_V5 = #channel{ +enrich_connack_caps(AckProps, ?IS_MQTT_V5 = Channel) -> + #channel{ clientinfo = #{ zone := Zone + }, + conninfo = #{ + receive_maximum := ReceiveMaximum } - } -) -> + } = Channel, #{ max_packet_size := MaxPktSize, max_qos_allowed := MaxQoS, @@ -2029,7 +2030,8 @@ enrich_connack_caps( 'Topic-Alias-Maximum' => MaxAlias, 'Wildcard-Subscription-Available' => flag(Wildcard), 'Subscription-Identifier-Available' => 1, - 'Shared-Subscription-Available' => flag(Shared) + 'Shared-Subscription-Available' => flag(Shared), + 'Receive-Maximum' => ReceiveMaximum }, %% MQTT 5.0 - 3.2.2.3.4: %% It is a Protocol Error to include Maximum QoS more than once, diff --git a/apps/emqx/test/emqx_client_SUITE.erl b/apps/emqx/test/emqx_client_SUITE.erl index bb4ef08269..3e5babd2e3 100644 --- a/apps/emqx/test/emqx_client_SUITE.erl +++ b/apps/emqx/test/emqx_client_SUITE.erl @@ -72,7 +72,7 @@ groups() -> t_dollar_topics, t_sub_non_utf8_topic ]}, - {mqttv5, [non_parallel_tests], [t_basic_with_props_v5]}, + {mqttv5, [non_parallel_tests], [t_basic_with_props_v5, t_v5_receive_maximim_in_connack]}, {others, [non_parallel_tests], [ t_username_as_clientid, t_certcn_as_clientid_default_config_tls, @@ -103,14 +103,14 @@ end_per_testcase(_Case, _Config) -> %%-------------------------------------------------------------------- t_basic_v3(_) -> - t_basic([{proto_ver, v3}]). + run_basic([{proto_ver, v3}]). %%-------------------------------------------------------------------- %% Test cases for MQTT v4 %%-------------------------------------------------------------------- t_basic_v4(_Config) -> - t_basic([{proto_ver, v4}]). + run_basic([{proto_ver, v4}]). t_cm(_) -> emqx_config:put_zone_conf(default, [mqtt, idle_timeout], 1000), @@ -335,19 +335,30 @@ t_sub_non_utf8_topic(_) -> %% Test cases for MQTT v5 %%-------------------------------------------------------------------- -t_basic_with_props_v5(_) -> - t_basic([ +v5_conn_props(ReceiveMaximum) -> + [ {proto_ver, v5}, - {properties, #{'Receive-Maximum' => 4}} - ]). + {properties, #{'Receive-Maximum' => ReceiveMaximum}} + ]. + +t_basic_with_props_v5(_) -> + run_basic(v5_conn_props(4)). + +t_v5_receive_maximim_in_connack(_) -> + ReceiveMaximum = 7, + {ok, C} = emqtt:start_link(v5_conn_props(ReceiveMaximum)), + {ok, Props} = emqtt:connect(C), + ?assertMatch(#{'Receive-Maximum' := ReceiveMaximum}, Props), + ok = emqtt:disconnect(C), + ok. %%-------------------------------------------------------------------- %% General test cases. %%-------------------------------------------------------------------- -t_basic(_Opts) -> +run_basic(Opts) -> Topic = nth(1, ?TOPICS), - {ok, C} = emqtt:start_link([{proto_ver, v4}]), + {ok, C} = emqtt:start_link(Opts), {ok, _} = emqtt:connect(C), {ok, _, [1]} = emqtt:subscribe(C, Topic, qos1), {ok, _, [2]} = emqtt:subscribe(C, Topic, qos2), diff --git a/changes/ce/fix-12492.en.md b/changes/ce/fix-12492.en.md new file mode 100644 index 0000000000..30a7b1399a --- /dev/null +++ b/changes/ce/fix-12492.en.md @@ -0,0 +1,4 @@ +Return `Receive-Maximum` in `CONNACK` for MQTT v5 clients. + +EMQX takes the min value of client's `Receive-Maximum` and server's `max_inflight` config as the max number of inflight (unacknowledged) messages allowed. +Prior to this fix, the value was not sent back to the client in `CONNACK` message.