From 3462bbd619d59df92bebd1261fb19f58fbf97cd3 Mon Sep 17 00:00:00 2001 From: tigercl Date: Wed, 12 Jun 2019 15:43:52 +0800 Subject: [PATCH 1/5] Fix retain in will message (#2607) * Fix retain in will message * Only handle retain available flag in MQTT v5 --- src/emqx_protocol.erl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/emqx_protocol.erl b/src/emqx_protocol.erl index 57f60c8c7..ec0826bf4 100644 --- a/src/emqx_protocol.erl +++ b/src/emqx_protocol.erl @@ -778,7 +778,8 @@ check_connect(Packet, PState) -> fun check_client_id/2, fun check_flapping/2, fun check_banned/2, - fun check_will_topic/2], Packet, PState). + fun check_will_topic/2, + fun check_will_retain/2], Packet, PState). check_proto_ver(#mqtt_packet_connect{proto_ver = Ver, proto_name = Name}, _PState) -> @@ -829,6 +830,16 @@ check_will_topic(#mqtt_packet_connect{will_topic = WillTopic} = ConnPkt, PState) {error, ?RC_TOPIC_NAME_INVALID} end. +check_will_retain(#mqtt_packet_connect{will_retain = false, proto_ver = ?MQTT_PROTO_V5}, _PState) -> + ok; +check_will_retain(#mqtt_packet_connect{will_retain = true, proto_ver = ?MQTT_PROTO_V5}, #pstate{zone = Zone}) -> + case emqx_zone:get_env(Zone, mqtt_retain_available, true) of + true -> {error, ?RC_RETAIN_NOT_SUPPORTED}; + false -> ok + end; +check_will_retain(_Packet, _PState) -> + ok. + check_will_acl(#mqtt_packet_connect{will_topic = WillTopic}, #pstate{zone = Zone, credentials = Credentials}) -> EnableAcl = emqx_zone:get_env(Zone, enable_acl, false), From 76525cc703b8ebbdd33be3ec5271cf2edc365f3b Mon Sep 17 00:00:00 2001 From: turtleDeng Date: Wed, 12 Jun 2019 15:49:18 +0800 Subject: [PATCH 2/5] Fix acl deny action logic (#2613) --- src/emqx_protocol.erl | 60 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/emqx_protocol.erl b/src/emqx_protocol.erl index ec0826bf4..f56d6a6e6 100644 --- a/src/emqx_protocol.erl +++ b/src/emqx_protocol.erl @@ -419,8 +419,7 @@ process(?CONNECT_PACKET( {ReasonCode, PState1} end); -process(Packet = ?PUBLISH_PACKET(?QOS_0, Topic, _PacketId, _Payload), - PState = #pstate{zone = Zone, proto_ver = ProtoVer}) -> +process(Packet = ?PUBLISH_PACKET(?QOS_0, Topic, _PacketId, _Payload), PState = #pstate{zone = Zone}) -> case check_publish(Packet, PState) of ok -> do_publish(Packet, PState); @@ -428,12 +427,10 @@ process(Packet = ?PUBLISH_PACKET(?QOS_0, Topic, _PacketId, _Payload), ?LOG(warning, "[Protocol] Cannot publish qos0 message to ~s for ~s", [Topic, emqx_reason_codes:text(ReasonCode)]), AclDenyAction = emqx_zone:get_env(Zone, acl_deny_action, ignore), - ErrorTerm = {error, emqx_reason_codes:name(?RC_NOT_AUTHORIZED, ProtoVer), PState}, - do_acl_deny_action(AclDenyAction, Packet, ReasonCode, ErrorTerm) + do_acl_deny_action(AclDenyAction, Packet, ReasonCode, PState) end; -process(Packet = ?PUBLISH_PACKET(?QOS_1, Topic, PacketId, _Payload), - PState = #pstate{zone = Zone, proto_ver = ProtoVer}) -> +process(Packet = ?PUBLISH_PACKET(?QOS_1, Topic, PacketId, _Payload), PState = #pstate{zone = Zone}) -> case check_publish(Packet, PState) of ok -> do_publish(Packet, PState); @@ -442,14 +439,12 @@ process(Packet = ?PUBLISH_PACKET(?QOS_1, Topic, PacketId, _Payload), case deliver({puback, PacketId, ReasonCode}, PState) of {ok, PState1} -> AclDenyAction = emqx_zone:get_env(Zone, acl_deny_action, ignore), - ErrorTerm = {error, emqx_reason_codes:name(?RC_NOT_AUTHORIZED, ProtoVer), PState1}, - do_acl_deny_action(AclDenyAction, Packet, ReasonCode, ErrorTerm); + do_acl_deny_action(AclDenyAction, Packet, ReasonCode, PState1); Error -> Error end end; -process(Packet = ?PUBLISH_PACKET(?QOS_2, Topic, PacketId, _Payload), - PState = #pstate{zone = Zone, proto_ver = ProtoVer}) -> +process(Packet = ?PUBLISH_PACKET(?QOS_2, Topic, PacketId, _Payload), PState = #pstate{zone = Zone}) -> case check_publish(Packet, PState) of ok -> do_publish(Packet, PState); @@ -459,8 +454,7 @@ process(Packet = ?PUBLISH_PACKET(?QOS_2, Topic, PacketId, _Payload), case deliver({pubrec, PacketId, ReasonCode}, PState) of {ok, PState1} -> AclDenyAction = emqx_zone:get_env(Zone, acl_deny_action, ignore), - ErrorTerm = {error, emqx_reason_codes:name(?RC_NOT_AUTHORIZED, ProtoVer), PState1}, - do_acl_deny_action(AclDenyAction, Packet, ReasonCode, ErrorTerm); + do_acl_deny_action(AclDenyAction, Packet, ReasonCode, PState1); Error -> Error end end; @@ -488,7 +482,7 @@ process(?PUBCOMP_PACKET(PacketId, ReasonCode), PState = #pstate{session = SPid}) {ok = emqx_session:pubcomp(SPid, PacketId, ReasonCode), PState}; process(Packet = ?SUBSCRIBE_PACKET(PacketId, Properties, RawTopicFilters), - PState = #pstate{zone = Zone, proto_ver = ProtoVer, session = SPid, credentials = Credentials}) -> + PState = #pstate{zone = Zone, session = SPid, credentials = Credentials}) -> case check_subscribe(parse_topic_filters(?SUBSCRIBE, raw_topic_filters(PState, RawTopicFilters)), PState) of {ok, TopicFilters} -> TopicFilters0 = emqx_hooks:run_fold('client.subscribe', [Credentials], TopicFilters), @@ -507,8 +501,7 @@ process(Packet = ?SUBSCRIBE_PACKET(PacketId, Properties, RawTopicFilters), case deliver({suback, PacketId, ReasonCodes}, PState) of {ok, PState1} -> AclDenyAction = emqx_zone:get_env(Zone, acl_deny_action, ignore), - ErrorTerm = {error, emqx_reason_codes:name(?RC_NOT_AUTHORIZED, ProtoVer), PState1}, - do_acl_deny_action(AclDenyAction, Packet, ReasonCodes, ErrorTerm); + do_acl_deny_action(AclDenyAction, Packet, ReasonCodes, PState1); Error -> Error end @@ -977,26 +970,33 @@ do_flapping_detect(Action, #pstate{zone = Zone, end. do_acl_deny_action(disconnect, ?PUBLISH_PACKET(?QOS_0, _Topic, _PacketId, _Payload), - ?RC_NOT_AUTHORIZED, ErrorTerm) -> - ErrorTerm; + ?RC_NOT_AUTHORIZED, PState = #pstate{proto_ver = ProtoVer}) -> + {error, emqx_reason_codes:name(?RC_NOT_AUTHORIZED, ProtoVer), PState}; do_acl_deny_action(disconnect, ?PUBLISH_PACKET(QoS, _Topic, _PacketId, _Payload), - ?RC_NOT_AUTHORIZED, ErrorTerm = {_Error, _CodeName, PState}) + ?RC_NOT_AUTHORIZED, PState = #pstate{proto_ver = ProtoVer}) when QoS =:= ?QOS_1; QoS =:= ?QOS_2 -> deliver({disconnect, ?RC_NOT_AUTHORIZED}, PState), - ErrorTerm; + {error, emqx_reason_codes:name(?RC_NOT_AUTHORIZED, ProtoVer), PState}; -do_acl_deny_action(disconnect, ?SUBSCRIBE_PACKET(_PacketId, _Properties, _RawTopicFilters), - ReasonCodes, ErrorTerm = {_Error, _CodeName, PState}) -> - case lists:member(?RC_NOT_AUTHORIZED, ReasonCodes) of - true -> - deliver({disconnect, ?RC_NOT_AUTHORIZED}, PState), - ErrorTerm; - false -> - {ok, PState} - end; -do_acl_deny_action(_OtherAction, _PubSupPacket, _ReasonCode, {_Error, _CodeName, PState}) -> - {ok, PState}. +do_acl_deny_action(Action, ?SUBSCRIBE_PACKET(_PacketId, _Properties, _RawTopicFilters), ReasonCodes, PState) + when is_list(ReasonCodes) -> + traverse_reason_codes(ReasonCodes, Action, PState); +do_acl_deny_action(_OtherAction, _PubSubPacket, ?RC_NOT_AUTHORIZED, PState) -> + {ok, PState}; +do_acl_deny_action(_OtherAction, _PubSubPacket, ReasonCode, PState = #pstate{proto_ver = ProtoVer}) -> + {error, emqx_reason_codes:name(ReasonCode, ProtoVer), PState}. + +traverse_reason_codes([], _Action, PState) -> + {ok, PState}; +traverse_reason_codes([?RC_SUCCESS | LeftReasonCodes], Action, PState) -> + traverse_reason_codes(LeftReasonCodes, Action, PState); +traverse_reason_codes([?RC_NOT_AUTHORIZED | _LeftReasonCodes], disconnect, PState = #pstate{proto_ver = ProtoVer}) -> + {error, emqx_reason_codes:name(?RC_NOT_AUTHORIZED, ProtoVer), PState}; +traverse_reason_codes([?RC_NOT_AUTHORIZED | LeftReasonCodes], Action, PState) -> + traverse_reason_codes(LeftReasonCodes, Action, PState); +traverse_reason_codes([OtherCode | _LeftReasonCodes], _Action, PState = #pstate{proto_ver = ProtoVer}) -> + {error, emqx_reason_codes:name(OtherCode, ProtoVer), PState}. %% Reason code compat reason_codes_compat(_PktType, ReasonCodes, ?MQTT_PROTO_V5) -> From e73c4c64d02a50bbef87366ce4946abf2123272b Mon Sep 17 00:00:00 2001 From: GilbertWong Date: Wed, 12 Jun 2019 14:50:29 +0800 Subject: [PATCH 3/5] Fix websocket bug. Prior to this change, websocket connection would be closed directly without sending connack packet when acl check fails. This change fix this bug. --- src/emqx_ws_connection.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emqx_ws_connection.erl b/src/emqx_ws_connection.erl index d635a0caa..29749f35c 100644 --- a/src/emqx_ws_connection.erl +++ b/src/emqx_ws_connection.erl @@ -301,7 +301,6 @@ websocket_info(Info, State) -> terminate(SockError, _Req, #state{keepalive = Keepalive, proto_state = ProtoState, shutdown = Shutdown}) -> - ?LOG(debug, "[WS Connection] Terminated for ~p, sockerror: ~p", [Shutdown, SockError]), emqx_keepalive:cancel(Keepalive), case {ProtoState, Shutdown} of @@ -327,7 +326,8 @@ ensure_stats_timer(State) -> State. shutdown(Reason, State) -> - {stop, State#state{shutdown = Reason}}. + self() ! {stop, State#state{shutdown = Reason}}, + {ok, State}. wsock_stats() -> [{Key, emqx_pd:get_counter(Key)} || Key <- ?SOCK_STATS]. From a3103cec7b92cf90f2a1caa5ae2957eb273cffcb Mon Sep 17 00:00:00 2001 From: turtleDeng Date: Wed, 12 Jun 2019 15:51:01 +0800 Subject: [PATCH 4/5] Revert "Fix websocket bug. Prior to this change, websocket connection would be closed directly without sending connack packet when acl check fails." This reverts commit e73c4c64d02a50bbef87366ce4946abf2123272b. --- src/emqx_ws_connection.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emqx_ws_connection.erl b/src/emqx_ws_connection.erl index 29749f35c..d635a0caa 100644 --- a/src/emqx_ws_connection.erl +++ b/src/emqx_ws_connection.erl @@ -301,6 +301,7 @@ websocket_info(Info, State) -> terminate(SockError, _Req, #state{keepalive = Keepalive, proto_state = ProtoState, shutdown = Shutdown}) -> + ?LOG(debug, "[WS Connection] Terminated for ~p, sockerror: ~p", [Shutdown, SockError]), emqx_keepalive:cancel(Keepalive), case {ProtoState, Shutdown} of @@ -326,8 +327,7 @@ ensure_stats_timer(State) -> State. shutdown(Reason, State) -> - self() ! {stop, State#state{shutdown = Reason}}, - {ok, State}. + {stop, State#state{shutdown = Reason}}. wsock_stats() -> [{Key, emqx_pd:get_counter(Key)} || Key <- ?SOCK_STATS]. From c4de0b1792c732788969f4b6fe544590d4167ecc Mon Sep 17 00:00:00 2001 From: terry-xiaoyu <506895667@qq.com> Date: Thu, 13 Jun 2019 12:03:05 +0800 Subject: [PATCH 5/5] No chars limit by default --- etc/emqx.conf | 4 ++-- priv/emqx.schema | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/emqx.conf b/etc/emqx.conf index dcae95e3b..4ad11388a 100644 --- a/etc/emqx.conf +++ b/etc/emqx.conf @@ -371,8 +371,8 @@ log.file = emqx.log ## Limits the total number of characters printed for each log event. ## ## Value: Integer -## Default: 8192 -log.chars_limit = 8192 +## Default: No Limit +#log.chars_limit = 8192 ## Maximum size of each log file. ## diff --git a/priv/emqx.schema b/priv/emqx.schema index 1d8e60a8f..561d1e770 100644 --- a/priv/emqx.schema +++ b/priv/emqx.schema @@ -421,7 +421,7 @@ end}. ]}. {mapping, "log.chars_limit", "kernel.logger", [ - {default, 8192}, + {default, -1}, {datatype, integer} ]}.