test: handle frame error for CONNECT packets

This commit is contained in:
JimMoen 2024-07-15 15:28:39 +08:00
parent 37a89d0094
commit 7a251c9ead
No known key found for this signature in database
2 changed files with 65 additions and 23 deletions

View File

@ -414,24 +414,32 @@ t_handle_in_auth(_) ->
emqx_channel:handle_in(?AUTH_PACKET(), Channel). emqx_channel:handle_in(?AUTH_PACKET(), Channel).
t_handle_in_frame_error(_) -> t_handle_in_frame_error(_) ->
IdleChannel = channel(#{conn_state => idle}), IdleChannelV5 = channel(#{conn_state => idle}),
{shutdown, #{shutdown_count := frame_too_large, cause := frame_too_large}, _Chan} = %% no CONNACK packet for v4
emqx_channel:handle_in({frame_error, #{cause => frame_too_large}}, IdleChannel), ?assertMatch(
{shutdown, #{shutdown_count := frame_too_large, cause := frame_too_large}, _Chan},
emqx_channel:handle_in(
{frame_error, #{cause => frame_too_large}}, v4(IdleChannelV5)
)
),
ConnectingChan = channel(#{conn_state => connecting}), ConnectingChan = channel(#{conn_state => connecting}),
ConnackPacket = ?CONNACK_PACKET(?RC_PACKET_TOO_LARGE), ConnackPacket = ?CONNACK_PACKET(?RC_PACKET_TOO_LARGE),
{shutdown, ?assertMatch(
#{ {shutdown,
shutdown_count := frame_too_large, #{
cause := frame_too_large, shutdown_count := frame_too_large,
limit := 100, cause := frame_too_large,
received := 101 limit := 100,
}, received := 101
ConnackPacket, },
_} = ConnackPacket, _},
emqx_channel:handle_in( emqx_channel:handle_in(
{frame_error, #{cause => frame_too_large, received => 101, limit => 100}}, {frame_error, #{cause => frame_too_large, received => 101, limit => 100}},
ConnectingChan ConnectingChan
), )
),
DisconnectPacket = ?DISCONNECT_PACKET(?RC_PACKET_TOO_LARGE), DisconnectPacket = ?DISCONNECT_PACKET(?RC_PACKET_TOO_LARGE),
ConnectedChan = channel(#{conn_state => connected}), ConnectedChan = channel(#{conn_state => connected}),
?assertMatch( ?assertMatch(

View File

@ -63,6 +63,7 @@ groups() ->
t_parse_malformed_properties, t_parse_malformed_properties,
t_malformed_connect_header, t_malformed_connect_header,
t_malformed_connect_data, t_malformed_connect_data,
t_malformed_connect_data_proto_ver,
t_reserved_connect_flag, t_reserved_connect_flag,
t_invalid_clientid, t_invalid_clientid,
t_undefined_password, t_undefined_password,
@ -167,6 +168,8 @@ t_parse_malformed_utf8_string(_) ->
ParseState = emqx_frame:initial_parse_state(#{strict_mode => true}), ParseState = emqx_frame:initial_parse_state(#{strict_mode => true}),
?ASSERT_FRAME_THROW(utf8_string_invalid, emqx_frame:parse(MalformedPacket, ParseState)). ?ASSERT_FRAME_THROW(utf8_string_invalid, emqx_frame:parse(MalformedPacket, ParseState)).
%% TODO: parse v3 with 0 length clientid
t_serialize_parse_v3_connect(_) -> t_serialize_parse_v3_connect(_) ->
Bin = Bin =
<<16, 37, 0, 6, 77, 81, 73, 115, 100, 112, 3, 2, 0, 60, 0, 23, 109, 111, 115, 113, 112, 117, <<16, 37, 0, 6, 77, 81, 73, 115, 100, 112, 3, 2, 0, 60, 0, 23, 109, 111, 115, 113, 112, 117,
@ -324,7 +327,7 @@ t_serialize_parse_bridge_connect(_) ->
header = #mqtt_packet_header{type = ?CONNECT}, header = #mqtt_packet_header{type = ?CONNECT},
variable = #mqtt_packet_connect{ variable = #mqtt_packet_connect{
clientid = <<"C_00:0C:29:2B:77:52">>, clientid = <<"C_00:0C:29:2B:77:52">>,
proto_ver = 16#03, proto_ver = ?MQTT_PROTO_V3,
proto_name = <<"MQIsdp">>, proto_name = <<"MQIsdp">>,
is_bridge = true, is_bridge = true,
will_retain = true, will_retain = true,
@ -686,15 +689,36 @@ t_malformed_connect_header(_) ->
). ).
t_malformed_connect_data(_) -> t_malformed_connect_data(_) ->
ProtoNameWithLen = <<0, 6, "MQIsdp">>,
ConnectFlags = <<2#00000000>>,
ClientIdwithLen = <<0, 1, "a">>,
UnexpectedRestBin = <<0, 1, 2>>,
?ASSERT_FRAME_THROW( ?ASSERT_FRAME_THROW(
#{cause := malformed_connect, unexpected_trailing_bytes := _}, #{cause := malformed_connect, unexpected_trailing_bytes := 3},
emqx_frame:parse(<<16, 15, 0, 6, 77, 81, 73, 115, 100, 112, 3, 0, 0, 0, 0, 0, 0>>) emqx_frame:parse(
<<16, 18, ProtoNameWithLen/binary, ?MQTT_PROTO_V3, ConnectFlags/binary, 0, 0,
ClientIdwithLen/binary, UnexpectedRestBin/binary>>
)
).
t_malformed_connect_data_proto_ver(_) ->
Proto3NameWithLen = <<0, 6, "MQIsdp">>,
?ASSERT_FRAME_THROW(
#{cause := malformed_connect, header_bytes := <<>>},
emqx_frame:parse(<<16, 8, Proto3NameWithLen/binary>>)
),
ProtoNameWithLen = <<0, 4, "MQTT">>,
?ASSERT_FRAME_THROW(
#{cause := malformed_connect, header_bytes := <<>>},
emqx_frame:parse(<<16, 6, ProtoNameWithLen/binary>>)
). ).
t_reserved_connect_flag(_) -> t_reserved_connect_flag(_) ->
?assertException( ?assertException(
throw, throw,
{frame_parse_error, reserved_connect_flag}, {frame_parse_error, #{
cause := reserved_connect_flag, proto_ver := ?MQTT_PROTO_V3, proto_name := <<"MQIsdp">>
}},
emqx_frame:parse(<<16, 15, 0, 6, 77, 81, 73, 115, 100, 112, 3, 1, 0, 0, 1, 0, 0>>) emqx_frame:parse(<<16, 15, 0, 6, 77, 81, 73, 115, 100, 112, 3, 1, 0, 0, 1, 0, 0>>)
). ).
@ -726,7 +750,7 @@ t_undefined_password(_) ->
}, },
variable = #mqtt_packet_connect{ variable = #mqtt_packet_connect{
proto_name = <<"MQTT">>, proto_name = <<"MQTT">>,
proto_ver = 4, proto_ver = ?MQTT_PROTO_V4,
is_bridge = false, is_bridge = false,
clean_start = true, clean_start = true,
will_flag = false, will_flag = false,
@ -774,7 +798,9 @@ t_invalid_will_retain(_) ->
54, 75, 78, 112, 57, 0, 6, 68, 103, 55, 87, 87, 87>>, 54, 75, 78, 112, 57, 0, 6, 68, 103, 55, 87, 87, 87>>,
?assertException( ?assertException(
throw, throw,
{frame_parse_error, invalid_will_retain}, {frame_parse_error, #{
cause := invalid_will_retain, proto_ver := ?MQTT_PROTO_V5, proto_name := <<"MQTT">>
}},
emqx_frame:parse(ConnectBin) emqx_frame:parse(ConnectBin)
), ),
ok. ok.
@ -796,22 +822,30 @@ t_invalid_will_qos(_) ->
), ),
?assertException( ?assertException(
throw, throw,
{frame_parse_error, invalid_will_qos}, {frame_parse_error, #{
cause := invalid_will_qos, proto_ver := ?MQTT_PROTO_V5, proto_name := <<"MQTT">>
}},
emqx_frame:parse(ConnectBinFun(Will_F_WillQoS1)) emqx_frame:parse(ConnectBinFun(Will_F_WillQoS1))
), ),
?assertException( ?assertException(
throw, throw,
{frame_parse_error, invalid_will_qos}, {frame_parse_error, #{
cause := invalid_will_qos, proto_ver := ?MQTT_PROTO_V5, proto_name := <<"MQTT">>
}},
emqx_frame:parse(ConnectBinFun(Will_F_WillQoS2)) emqx_frame:parse(ConnectBinFun(Will_F_WillQoS2))
), ),
?assertException( ?assertException(
throw, throw,
{frame_parse_error, invalid_will_qos}, {frame_parse_error, #{
cause := invalid_will_qos, proto_ver := ?MQTT_PROTO_V5, proto_name := <<"MQTT">>
}},
emqx_frame:parse(ConnectBinFun(Will_F_WillQoS3)) emqx_frame:parse(ConnectBinFun(Will_F_WillQoS3))
), ),
?assertException( ?assertException(
throw, throw,
{frame_parse_error, invalid_will_qos}, {frame_parse_error, #{
cause := invalid_will_qos, proto_ver := ?MQTT_PROTO_V5, proto_name := <<"MQTT">>
}},
emqx_frame:parse(ConnectBinFun(Will_T_WillQoS3)) emqx_frame:parse(ConnectBinFun(Will_T_WillQoS3))
), ),
ok. ok.