From aab6dcf8d1369ba360b21424054b1ad55c13c952 Mon Sep 17 00:00:00 2001 From: Ery Lee Date: Tue, 21 Apr 2015 12:14:27 +0800 Subject: [PATCH] fix issues#101 - access_control for PUBLISH packet should be optimized --- apps/emqttd/src/emqttd_protocol.erl | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/apps/emqttd/src/emqttd_protocol.erl b/apps/emqttd/src/emqttd_protocol.erl index 592de67e6..a4d50a55e 100644 --- a/apps/emqttd/src/emqttd_protocol.erl +++ b/apps/emqttd/src/emqttd_protocol.erl @@ -146,7 +146,7 @@ handle(Packet = ?CONNECT_PACKET(Var), State = #proto_state{peername = Peername = handle(Packet = ?PUBLISH_PACKET(?QOS_0, Topic, _PacketId, _Payload), State = #proto_state{clientid = ClientId, session = Session}) -> - case emqttd_access_control:check_acl(client(State), publish, Topic) of + case check_acl(publish, Topic, State) of allow -> emqttd_session:publish(Session, ClientId, {?QOS_0, emqtt_message:from_packet(Packet)}); deny -> @@ -156,7 +156,7 @@ handle(Packet = ?PUBLISH_PACKET(?QOS_0, Topic, _PacketId, _Payload), handle(Packet = ?PUBLISH_PACKET(?QOS_1, Topic, PacketId, _Payload), State = #proto_state{clientid = ClientId, session = Session}) -> - case emqttd_access_control:check_acl(client(State), publish, Topic) of + case check_acl(publish, Topic, State) of allow -> emqttd_session:publish(Session, ClientId, {?QOS_1, emqtt_message:from_packet(Packet)}), send(?PUBACK_PACKET(?PUBACK, PacketId), State); @@ -167,7 +167,7 @@ handle(Packet = ?PUBLISH_PACKET(?QOS_1, Topic, PacketId, _Payload), handle(Packet = ?PUBLISH_PACKET(?QOS_2, Topic, PacketId, _Payload), State = #proto_state{clientid = ClientId, session = Session}) -> - case emqttd_access_control:check_acl(client(State), publish, Topic) of + case check_acl(publish, Topic, State) of allow -> NewSession = emqttd_session:publish(Session, ClientId, {?QOS_2, emqtt_message:from_packet(Packet)}), send(?PUBACK_PACKET(?PUBREC, PacketId), State#proto_state{session = NewSession}); @@ -191,7 +191,7 @@ handle(?PUBACK_PACKET(Type, PacketId), State = #proto_state{session = Session}) {ok, NewState}; handle(?SUBSCRIBE_PACKET(PacketId, TopicTable), State = #proto_state{clientid = ClientId, session = Session}) -> - AllowDenies = [emqttd_access_control:check_acl(client(State), subscribe, Topic) || {Topic, _Qos} <- TopicTable], + AllowDenies = [check_acl(subscribe, Topic, State) || {Topic, _Qos} <- TopicTable], case lists:member(deny, AllowDenies) of true -> %%TODO: return 128 QoS when deny... @@ -343,6 +343,20 @@ validate_qos(_) -> false. try_unregister(undefined, _) -> ok; try_unregister(ClientId, _) -> emqttd_cm:unregister(ClientId). +%% publish ACL is cached in process dictionary. +check_acl(publish, Topic, State) -> + case get({acl, publish, Topic}) of + undefined -> + AllowDeny = emqttd_access_control:check_acl(client(State), publish, Topic), + put({acl, publish, Topic}, AllowDeny), + AllowDeny; + AllowDeny -> + AllowDeny + end; + +check_acl(subscribe, Topic, State) -> + emqttd_access_control:check_acl(client(State), subscribe, Topic). + sent_stats(?PACKET(Type)) -> emqttd_metrics:inc('packets/sent'), inc(Type).