Преглед изворни кода

Fix unexpected packet before connected

zhouzb пре 5 година
родитељ
комит
83b1f3e6c8
2 измењених фајлова са 13 додато и 2 уклоњено
  1. 7 2
      src/emqx_channel.erl
  2. 6 0
      test/emqx_channel_SUITE.erl

+ 7 - 2
src/emqx_channel.erl

@@ -250,8 +250,10 @@ handle_in(Packet = ?AUTH_PACKET(?RC_CONTINUE_AUTHENTICATION, _Properties), Chann
             case ConnState of
                 connecting ->
                     process_connect(NProperties, ensure_connected(NChannel));
+                connected ->
+                    handle_out(auth, {?RC_SUCCESS, NProperties}, NChannel);
                 _ ->
-                    handle_out(auth, {?RC_SUCCESS, NProperties}, NChannel)
+                    handle_out(disconnect, ?RC_PROTOCOL_ERROR, Channel)
             end;
         {continue, NProperties, NChannel} ->
             handle_out(auth, {?RC_CONTINUE_AUTHENTICATION, NProperties}, NChannel);
@@ -259,7 +261,7 @@ handle_in(Packet = ?AUTH_PACKET(?RC_CONTINUE_AUTHENTICATION, _Properties), Chann
             handle_out(connack, NReasonCode, NChannel)
     end;
 
-handle_in(Packet = ?AUTH_PACKET(?RC_RE_AUTHENTICATE, _Properties), Channel) ->
+handle_in(Packet = ?AUTH_PACKET(?RC_RE_AUTHENTICATE, _Properties), Channel = #channel{conn_state = connected}) ->
     case enhanced_auth(Packet, Channel) of
         {ok, NProperties, NChannel} ->
             handle_out(auth, {?RC_SUCCESS, NProperties}, NChannel);
@@ -269,6 +271,9 @@ handle_in(Packet = ?AUTH_PACKET(?RC_RE_AUTHENTICATE, _Properties), Channel) ->
             handle_out(disconnect, NReasonCode, NChannel)
     end;
 
+handle_in(?PACKET(_), Channel = #channel{conn_state = ConnState}) when ConnState =/= connected ->
+    handle_out(disconnect, ?RC_PROTOCOL_ERROR, Channel);
+
 handle_in(Packet = ?PUBLISH_PACKET(_QoS), Channel) ->
     case emqx_packet:check(Packet) of
         ok -> process_publish(Packet, Channel);

+ 6 - 0
test/emqx_channel_SUITE.erl

@@ -112,6 +112,12 @@ t_handle_in_unexpected_connect_packet(_) ->
     {ok, [{outgoing, Packet}, {close, protocol_error}], Channel} =
         emqx_channel:handle_in(?CONNECT_PACKET(connpkt()), Channel).
 
+t_handle_in_unexpected_packet(_) ->
+    Channel = emqx_channel:set_field(conn_state, idle, channel()),
+    Packet = ?DISCONNECT_PACKET(?RC_PROTOCOL_ERROR),
+    {ok, [{outgoing, Packet}, {close, protocol_error}], Channel} =
+        emqx_channel:handle_in(?PUBLISH_PACKET(?QOS_0), Channel).
+
 t_handle_in_connect_auth_failed(_) ->
     ConnPkt = #mqtt_packet_connect{
                                 proto_name  = <<"MQTT">>,