From 5c901a52bdb871115192c4df90bef76df51a9a2b Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 5 Jul 2023 16:08:20 +0800 Subject: [PATCH 1/5] fix(coap): make username/password optinal in connection --- apps/emqx_gateway/src/emqx_gateway_utils.erl | 6 +- .../src/emqx_coap_channel.erl | 61 ++++++++----------- 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/apps/emqx_gateway/src/emqx_gateway_utils.erl b/apps/emqx_gateway/src/emqx_gateway_utils.erl index 634a02f03..eb4ce9fdf 100644 --- a/apps/emqx_gateway/src/emqx_gateway_utils.erl +++ b/apps/emqx_gateway/src/emqx_gateway_utils.erl @@ -46,7 +46,8 @@ global_chain/1, listener_chain/3, find_gateway_definitions/0, - plus_max_connections/2 + plus_max_connections/2, + random_clientid/1 ]). -export([stringfy/1]). @@ -631,3 +632,6 @@ ensure_gateway_loaded() -> emqx_gateway_mqttsn ] ). + +random_clientid(GwName) when is_atom(GwName) -> + iolist_to_binary([atom_to_list(GwName), "-", emqx_utils:gen_id()]). diff --git a/apps/emqx_gateway_coap/src/emqx_coap_channel.erl b/apps/emqx_gateway_coap/src/emqx_coap_channel.erl index 21066655e..a48589e36 100644 --- a/apps/emqx_gateway_coap/src/emqx_coap_channel.erl +++ b/apps/emqx_gateway_coap/src/emqx_coap_channel.erl @@ -486,46 +486,35 @@ enrich_conninfo( conninfo = ConnInfo } ) -> - %% FIXME: generate a random clientid if absent - case Queries of - #{<<"clientid">> := ClientId} -> - Interval = maps:get(interval, emqx_keepalive:info(KeepAlive)), - NConnInfo = ConnInfo#{ - clientid => ClientId, - proto_name => <<"CoAP">>, - proto_ver => <<"1">>, - clean_start => true, - keepalive => Interval, - expiry_interval => 0 - }, - {ok, Channel#channel{conninfo = NConnInfo}}; - _ -> - {error, "invalid queries", Channel} - end. + ClientId = + case maps:get(<<"clientid">>, Queries, undefined) of + undefined -> + emqx_gateway_utils:random_clientid(coap); + ClientId0 -> + ClientId0 + end, + Interval = maps:get(interval, emqx_keepalive:info(KeepAlive)), + NConnInfo = ConnInfo#{ + clientid => ClientId, + proto_name => <<"CoAP">>, + proto_ver => <<"1">>, + clean_start => true, + keepalive => Interval, + expiry_interval => 0 + }, + {ok, Channel#channel{conninfo = NConnInfo}}. enrich_clientinfo( {Queries, Msg}, - Channel = #channel{clientinfo = ClientInfo0} + Channel = #channel{conninfo = ConnInfo, clientinfo = ClientInfo0} ) -> - %% FIXME: - %% 1. generate a random clientid if absent; - %% 2. assgin username, password to `undefined` if absent - case Queries of - #{ - <<"username">> := UserName, - <<"password">> := Password, - <<"clientid">> := ClientId - } -> - ClientInfo = ClientInfo0#{ - username => UserName, - password => Password, - clientid => ClientId - }, - {ok, NClientInfo} = fix_mountpoint(Msg, ClientInfo), - {ok, Channel#channel{clientinfo = NClientInfo}}; - _ -> - {error, "invalid queries", Channel} - end. + ClientInfo = ClientInfo0#{ + clientid => maps:get(clientid, ConnInfo), + username => maps:get(<<"username">>, Queries, undefined), + password => maps:get(<<"password">>, Queries, undefined) + }, + {ok, NClientInfo} = fix_mountpoint(Msg, ClientInfo), + {ok, Channel#channel{clientinfo = NClientInfo}}. set_log_meta(_Input, #channel{clientinfo = #{clientid := ClientId}}) -> emqx_logger:set_metadata_clientid(ClientId), From 800b1545826e300d0078552afba832cb39c5c33e Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 5 Jul 2023 16:24:15 +0800 Subject: [PATCH 2/5] test(coap): cover the params optional logic to create connection --- .../src/emqx_coap_channel.erl | 32 ++++++++--------- .../test/emqx_coap_SUITE.erl | 36 +++++++++++++++++++ .../src/emqx_exproto_channel.erl | 5 +-- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/apps/emqx_gateway_coap/src/emqx_coap_channel.erl b/apps/emqx_gateway_coap/src/emqx_coap_channel.erl index a48589e36..bcafda41f 100644 --- a/apps/emqx_gateway_coap/src/emqx_coap_channel.erl +++ b/apps/emqx_gateway_coap/src/emqx_coap_channel.erl @@ -486,23 +486,21 @@ enrich_conninfo( conninfo = ConnInfo } ) -> - ClientId = - case maps:get(<<"clientid">>, Queries, undefined) of - undefined -> - emqx_gateway_utils:random_clientid(coap); - ClientId0 -> - ClientId0 - end, - Interval = maps:get(interval, emqx_keepalive:info(KeepAlive)), - NConnInfo = ConnInfo#{ - clientid => ClientId, - proto_name => <<"CoAP">>, - proto_ver => <<"1">>, - clean_start => true, - keepalive => Interval, - expiry_interval => 0 - }, - {ok, Channel#channel{conninfo = NConnInfo}}. + case Queries of + #{<<"clientid">> := ClientId} -> + Interval = maps:get(interval, emqx_keepalive:info(KeepAlive)), + NConnInfo = ConnInfo#{ + clientid => ClientId, + proto_name => <<"CoAP">>, + proto_ver => <<"1">>, + clean_start => true, + keepalive => Interval, + expiry_interval => 0 + }, + {ok, Channel#channel{conninfo = NConnInfo}}; + _ -> + {error, "clientid is required", Channel} + end. enrich_clientinfo( {Queries, Msg}, diff --git a/apps/emqx_gateway_coap/test/emqx_coap_SUITE.erl b/apps/emqx_gateway_coap/test/emqx_coap_SUITE.erl index 999493a79..95fdf8cca 100644 --- a/apps/emqx_gateway_coap/test/emqx_coap_SUITE.erl +++ b/apps/emqx_gateway_coap/test/emqx_coap_SUITE.erl @@ -133,6 +133,42 @@ t_connection(_) -> end, do(Action). +t_connection_optional_params(_) -> + UsernamePasswordAreOptional = + fun(Channel) -> + URI = + ?MQTT_PREFIX ++ + "/connection?clientid=client1", + Req = make_req(post), + {ok, created, Data} = do_request(Channel, URI, Req), + #coap_content{payload = Token0} = Data, + Token = binary_to_list(Token0), + + timer:sleep(100), + ?assertNotEqual( + [], + emqx_gateway_cm_registry:lookup_channels(coap, <<"client1">>) + ), + + disconnection(Channel, Token), + + timer:sleep(100), + ?assertEqual( + [], + emqx_gateway_cm_registry:lookup_channels(coap, <<"client1">>) + ) + end, + ClientIdIsRequired = + fun(Channel) -> + URI = + ?MQTT_PREFIX ++ + "/connection", + Req = make_req(post), + {error, bad_request, _} = do_request(Channel, URI, Req) + end, + do(UsernamePasswordAreOptional), + do(ClientIdIsRequired). + t_connection_with_authn_failed(_) -> ChId = {{127, 0, 0, 1}, 5683}, {ok, Sock} = er_coap_udp_socket:start_link(), diff --git a/apps/emqx_gateway_exproto/src/emqx_exproto_channel.erl b/apps/emqx_gateway_exproto/src/emqx_exproto_channel.erl index 2a144ffeb..5de597920 100644 --- a/apps/emqx_gateway_exproto/src/emqx_exproto_channel.erl +++ b/apps/emqx_gateway_exproto/src/emqx_exproto_channel.erl @@ -782,7 +782,7 @@ enrich_clientinfo(InClientInfo = #{proto_name := ProtoName}, ClientInfo) -> default_conninfo(ConnInfo) -> ConnInfo#{ clean_start => true, - clientid => anonymous_clientid(), + clientid => emqx_gateway_utils:random_clientid(exproto), username => undefined, conn_props => #{}, connected => true, @@ -822,6 +822,3 @@ proto_name_to_protocol(<<>>) -> exproto; proto_name_to_protocol(ProtoName) when is_binary(ProtoName) -> binary_to_atom(ProtoName). - -anonymous_clientid() -> - iolist_to_binary(["exproto-", emqx_utils:gen_id()]). From 6d2222318d2a61d7f5a46d5e0083bb339c54fd10 Mon Sep 17 00:00:00 2001 From: JianBo He Date: Thu, 6 Jul 2023 14:54:48 +0800 Subject: [PATCH 3/5] chore(coap): update the subscriptions_cnt stats in time --- apps/emqx_gateway_coap/src/emqx_coap_channel.erl | 8 ++++---- apps/emqx_gateway_coap/src/emqx_coap_session.erl | 8 ++++---- apps/emqx_gateway_coap/test/emqx_coap_SUITE.erl | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/apps/emqx_gateway_coap/src/emqx_coap_channel.erl b/apps/emqx_gateway_coap/src/emqx_coap_channel.erl index bcafda41f..d95dc5bd2 100644 --- a/apps/emqx_gateway_coap/src/emqx_coap_channel.erl +++ b/apps/emqx_gateway_coap/src/emqx_coap_channel.erl @@ -118,8 +118,8 @@ info(ctx, #channel{ctx = Ctx}) -> Ctx. -spec stats(channel()) -> emqx_types:stats(). -stats(_) -> - []. +stats(#channel{session = Session}) -> + emqx_coap_session:stats(Session). -spec init(map(), map()) -> channel(). init( @@ -273,7 +273,7 @@ handle_call( SubReq, TempMsg, #{}, Session ), NSession = maps:get(session, Result), - {reply, {ok, {MountedTopic, NSubOpts}}, Channel#channel{session = NSession}}; + {reply, {ok, {MountedTopic, NSubOpts}}, [{event, updated}], Channel#channel{session = NSession}}; handle_call( {unsubscribe, Topic}, _From, @@ -300,7 +300,7 @@ handle_call( UnSubReq, TempMsg, #{}, Session ), NSession = maps:get(session, Result), - {reply, ok, Channel#channel{session = NSession}}; + {reply, ok, [{event, updated}], Channel#channel{session = NSession}}; handle_call(subscriptions, _From, Channel = #channel{session = Session}) -> Subs = emqx_coap_session:info(subscriptions, Session), {reply, {ok, maps:to_list(Subs)}, Channel}; diff --git a/apps/emqx_gateway_coap/src/emqx_coap_session.erl b/apps/emqx_gateway_coap/src/emqx_coap_session.erl index 5ae169675..562369e2f 100644 --- a/apps/emqx_gateway_coap/src/emqx_coap_session.erl +++ b/apps/emqx_gateway_coap/src/emqx_coap_session.erl @@ -117,15 +117,15 @@ info(inflight, _) -> info(inflight_cnt, _) -> 0; info(inflight_max, _) -> - 0; + infinity; info(retry_interval, _) -> infinity; info(mqueue, _) -> emqx_mqueue:init(#{max_len => 0, store_qos0 => false}); -info(mqueue_len, #session{transport_manager = TM}) -> - maps:size(TM); -info(mqueue_max, _) -> +info(mqueue_len, _) -> 0; +info(mqueue_max, _) -> + infinity; info(mqueue_dropped, _) -> 0; info(next_pkt_id, _) -> diff --git a/apps/emqx_gateway_coap/test/emqx_coap_SUITE.erl b/apps/emqx_gateway_coap/test/emqx_coap_SUITE.erl index 95fdf8cca..ce809184e 100644 --- a/apps/emqx_gateway_coap/test/emqx_coap_SUITE.erl +++ b/apps/emqx_gateway_coap/test/emqx_coap_SUITE.erl @@ -363,6 +363,9 @@ t_clients_subscription_api(_) -> maps:get(topic, SubsResp2) ), + %% check subscription_cnt + {200, #{subscriptions_cnt := 1}} = request(get, "/gateways/coap/clients/client1"), + {204, _} = request(delete, Path ++ "/tx"), {200, []} = request(get, Path) From bc1efdc4a7cfcaa720212b9cebbba6da25cde81b Mon Sep 17 00:00:00 2001 From: JianBo He Date: Thu, 6 Jul 2023 14:59:01 +0800 Subject: [PATCH 4/5] chore: update changes --- changes/ce/fix-11206.en.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/ce/fix-11206.en.md diff --git a/changes/ce/fix-11206.en.md b/changes/ce/fix-11206.en.md new file mode 100644 index 000000000..e16b1e3f8 --- /dev/null +++ b/changes/ce/fix-11206.en.md @@ -0,0 +1 @@ +Make the username and password params of CoAP client to optional in connection mode. From 791b8ef671b2608c67cc8a230ccc532d9ded7447 Mon Sep 17 00:00:00 2001 From: JianBo He Date: Thu, 6 Jul 2023 16:31:47 +0800 Subject: [PATCH 5/5] chore: bump versions --- apps/emqx_gateway/src/emqx_gateway.app.src | 2 +- apps/emqx_gateway_coap/src/emqx_gateway_coap.app.src | 2 +- apps/emqx_gateway_exproto/src/emqx_gateway_exproto.app.src | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/emqx_gateway/src/emqx_gateway.app.src b/apps/emqx_gateway/src/emqx_gateway.app.src index bfcf4f2f2..6db4b0674 100644 --- a/apps/emqx_gateway/src/emqx_gateway.app.src +++ b/apps/emqx_gateway/src/emqx_gateway.app.src @@ -1,7 +1,7 @@ %% -*- mode: erlang -*- {application, emqx_gateway, [ {description, "The Gateway management application"}, - {vsn, "0.1.20"}, + {vsn, "0.1.21"}, {registered, []}, {mod, {emqx_gateway_app, []}}, {applications, [kernel, stdlib, emqx, emqx_authn, emqx_ctl]}, diff --git a/apps/emqx_gateway_coap/src/emqx_gateway_coap.app.src b/apps/emqx_gateway_coap/src/emqx_gateway_coap.app.src index e03066695..a0cbc3e18 100644 --- a/apps/emqx_gateway_coap/src/emqx_gateway_coap.app.src +++ b/apps/emqx_gateway_coap/src/emqx_gateway_coap.app.src @@ -1,6 +1,6 @@ {application, emqx_gateway_coap, [ {description, "CoAP Gateway"}, - {vsn, "0.1.1"}, + {vsn, "0.1.2"}, {registered, []}, {applications, [kernel, stdlib, emqx, emqx_gateway]}, {env, []}, diff --git a/apps/emqx_gateway_exproto/src/emqx_gateway_exproto.app.src b/apps/emqx_gateway_exproto/src/emqx_gateway_exproto.app.src index 66f9ddc89..5959eea3d 100644 --- a/apps/emqx_gateway_exproto/src/emqx_gateway_exproto.app.src +++ b/apps/emqx_gateway_exproto/src/emqx_gateway_exproto.app.src @@ -1,6 +1,6 @@ {application, emqx_gateway_exproto, [ {description, "ExProto Gateway"}, - {vsn, "0.1.2"}, + {vsn, "0.1.3"}, {registered, []}, {applications, [kernel, stdlib, grpc, emqx, emqx_gateway]}, {env, []},