mirror of
https://github.com/seriyps/mtproto_proxy.git
synced 2026-05-13 08:46:46 +00:00
Refactor codecs
* Get rid of per-codec internal read buffer
This commit is contained in:
parent
6590a56e7c
commit
1429cfe267
13 changed files with 132 additions and 111 deletions
|
|
@ -16,7 +16,7 @@
|
|||
-dialyzer(no_improper_lists).
|
||||
|
||||
-record(st,
|
||||
{buffer = <<>> :: binary()}).
|
||||
{}).
|
||||
-define(MAX_PACKET_SIZE, 1 * 1024 * 1024). % 1mb
|
||||
-define(APP, mtproto_proxy).
|
||||
|
||||
|
|
@ -25,33 +25,31 @@
|
|||
new() ->
|
||||
#st{}.
|
||||
|
||||
-spec try_decode_packet(binary(), codec()) -> {ok, binary(), codec()}
|
||||
-spec try_decode_packet(binary(), codec()) -> {ok, binary(), binary(), codec()}
|
||||
| {incomplete, codec()}.
|
||||
try_decode_packet(<<Flag, Len:24/unsigned-little-integer, Rest/binary>> = Data,
|
||||
#st{buffer = <<>>} = St) when Flag == 127; Flag == 255 ->
|
||||
try_decode_packet(<<Flag, Len:24/unsigned-little-integer, Rest/binary>>,
|
||||
#st{} = St) when Flag == 127; Flag == 255 ->
|
||||
Len1 = Len * 4,
|
||||
try_decode_packet_len(Len1, Rest, Data, St);
|
||||
try_decode_packet(<<Len, Rest/binary>> = Data,
|
||||
#st{buffer = <<>>} = St) when Len >= 128 ->
|
||||
try_decode_packet_len(Len1, Rest, St);
|
||||
try_decode_packet(<<Len, Rest/binary>>,
|
||||
#st{} = St) when Len >= 128 ->
|
||||
Len1 = (Len - 128) * 4,
|
||||
try_decode_packet_len(Len1, Rest, Data, St);
|
||||
try_decode_packet(<<Len, Rest/binary>> = Data,
|
||||
#st{buffer = <<>>} = St) when Len < 127 ->
|
||||
try_decode_packet_len(Len1, Rest, St);
|
||||
try_decode_packet(<<Len, Rest/binary>>,
|
||||
#st{} = St) when Len < 127 ->
|
||||
Len1 = Len * 4,
|
||||
try_decode_packet_len(Len1, Rest, Data, St);
|
||||
try_decode_packet(Bin, #st{buffer = Buf} = St) when byte_size(Buf) > 0 ->
|
||||
try_decode_packet(<<Buf/binary, Bin/binary>>, St#st{buffer = <<>>});
|
||||
try_decode_packet(Bin, #st{buffer = <<>>} = St) ->
|
||||
{incomplete, St#st{buffer = Bin}}.
|
||||
try_decode_packet_len(Len1, Rest, St);
|
||||
try_decode_packet(_, St) ->
|
||||
{incomplete, St}.
|
||||
|
||||
try_decode_packet_len(Len, LenStripped, Data, St) ->
|
||||
try_decode_packet_len(Len, LenStripped, St) ->
|
||||
(Len < ?MAX_PACKET_SIZE)
|
||||
orelse error({protocol_error, abridged_max_size, Len}),
|
||||
case LenStripped of
|
||||
<<Packet:Len/binary, Rest/binary>> ->
|
||||
{ok, Packet, St#st{buffer = Rest}};
|
||||
{ok, Packet, Rest, St};
|
||||
_ ->
|
||||
{incomplete, St#st{buffer = Data}}
|
||||
{incomplete, St}
|
||||
end.
|
||||
|
||||
-spec encode_packet(binary(), codec()) -> {iodata(), codec()}.
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@
|
|||
-export_type([codec/0]).
|
||||
|
||||
-record(baes_st,
|
||||
{decode_buf :: binary(),
|
||||
block_size :: pos_integer(),
|
||||
{block_size :: pos_integer(),
|
||||
encrypt :: any(), % aes state
|
||||
decrypt :: any() % aes state
|
||||
}).
|
||||
|
|
@ -30,7 +29,6 @@
|
|||
|
||||
new(EncKey, EncIv, DecKey, DecIv, BlockSize) ->
|
||||
#baes_st{
|
||||
decode_buf = <<>>,
|
||||
block_size = BlockSize,
|
||||
encrypt = {EncKey, EncIv},
|
||||
decrypt = {DecKey, DecIv}
|
||||
|
|
@ -45,40 +43,37 @@ encrypt(Data, #baes_st{block_size = BSize,
|
|||
{Encrypted, S#baes_st{encrypt = {EncKey, crypto:next_iv(aes_cbc, Encrypted)}}}.
|
||||
|
||||
|
||||
-spec decrypt(binary(), codec()) -> {binary(), codec()}.
|
||||
decrypt(Data, #baes_st{block_size = BSize,
|
||||
decode_buf = <<>>} = S) ->
|
||||
-spec decrypt(binary(), codec()) -> {Data :: binary(), Tail :: binary(), codec()}.
|
||||
decrypt(Data, #baes_st{block_size = BSize} = S) ->
|
||||
Size = byte_size(Data),
|
||||
Div = Size div BSize,
|
||||
Rem = Size rem BSize,
|
||||
case {Div, Rem} of
|
||||
{0, _} ->
|
||||
%% Not enough bytes
|
||||
{<<>>, S#baes_st{decode_buf = Data}};
|
||||
{<<>>, Data, S};
|
||||
{_, 0} ->
|
||||
%% Aligned
|
||||
do_decrypt(Data, S);
|
||||
do_decrypt(Data, <<>>, S);
|
||||
{_, Tail} ->
|
||||
%% N blocks + reminder
|
||||
Head = Size - Tail,
|
||||
<<ToDecode:Head/binary, Reminder/binary>> = Data,
|
||||
do_decrypt(ToDecode, S#baes_st{decode_buf = Reminder})
|
||||
end;
|
||||
decrypt(Data, #baes_st{decode_buf = Buf} = S) ->
|
||||
decrypt(<<Buf/binary, Data/binary>>, S#baes_st{decode_buf = <<>>}).
|
||||
do_decrypt(ToDecode, Reminder, S)
|
||||
end.
|
||||
|
||||
do_decrypt(Data, #baes_st{decrypt = {DecKey, DecIv}} = S) ->
|
||||
do_decrypt(Data, Tail, #baes_st{decrypt = {DecKey, DecIv}} = S) ->
|
||||
Decrypted = crypto:block_decrypt(aes_cbc, DecKey, DecIv, Data),
|
||||
NewDecIv = crypto:next_iv(aes_cbc, Data),
|
||||
{Decrypted, S#baes_st{decrypt = {DecKey, NewDecIv}}}.
|
||||
{Decrypted, Tail, S#baes_st{decrypt = {DecKey, NewDecIv}}}.
|
||||
|
||||
%% To comply mtp_layer interface
|
||||
try_decode_packet(Bin, S) ->
|
||||
case decrypt(Bin, S) of
|
||||
{<<>>, S1} ->
|
||||
{<<>>, _Tail, S1} ->
|
||||
{incomplete, S1};
|
||||
{Dec, S1} ->
|
||||
{ok, Dec, S1}
|
||||
{Dec, Tail, S1} ->
|
||||
{ok, Dec, Tail, S1}
|
||||
end.
|
||||
|
||||
encode_packet(Bin, S) ->
|
||||
|
|
@ -107,7 +102,7 @@ decrypt_test() ->
|
|||
],
|
||||
lists:foldl(
|
||||
fun({In, Out}, S1) ->
|
||||
{Dec, S2} = decrypt(In, S1),
|
||||
{Dec, <<>>, S2} = decrypt(In, S1),
|
||||
?assertEqual(Out, Dec),
|
||||
S2
|
||||
end, S, Samples).
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@
|
|||
decompose/1,
|
||||
try_decode_packet/2,
|
||||
encode_packet/2,
|
||||
fold_packets/4]).
|
||||
fold_packets/4,
|
||||
is_empty/1]).
|
||||
-export_type([codec/0]).
|
||||
|
||||
-type state() :: any().
|
||||
|
|
@ -30,13 +31,15 @@
|
|||
-record(codec,
|
||||
{crypto_mod :: crypto_codec(),
|
||||
crypto_state :: any(),
|
||||
crypto_buf = <<>> :: binary(),
|
||||
packet_mod :: packet_codec(),
|
||||
packet_state :: any()}).
|
||||
packet_state :: any(),
|
||||
packet_buf = <<>> :: binary()}).
|
||||
|
||||
-define(APP, mtproto_proxy).
|
||||
|
||||
-callback try_decode_packet(binary(), state()) ->
|
||||
{ok, binary(), state()}
|
||||
{ok, Packet :: binary(), Tail :: binary(), state()}
|
||||
| {incomplete, state()}.
|
||||
|
||||
-callback encode_packet(iodata(), state()) ->
|
||||
|
|
@ -60,26 +63,48 @@ decompose(#codec{crypto_mod = CryptoMod, crypto_state = CryptoState,
|
|||
|
||||
%% try_decode_packet(Inner) |> try_decode_packet(Outer)
|
||||
-spec try_decode_packet(binary(), codec()) -> {ok, binary(), codec()} | {incomplete, codec()}.
|
||||
try_decode_packet(Bin, #codec{crypto_mod = CryptoMod,
|
||||
crypto_state = CryptoSt,
|
||||
packet_mod = PacketMod,
|
||||
packet_state = PacketSt} = S) ->
|
||||
{Dec1, CryptoSt1} =
|
||||
case CryptoMod:try_decode_packet(Bin, CryptoSt) of
|
||||
{incomplete, PacketSt1_} ->
|
||||
%% We have to check if something is left in packet's buffers
|
||||
{<<>>, PacketSt1_};
|
||||
{ok, Dec1_, PacketSt1_} ->
|
||||
{Dec1_, PacketSt1_}
|
||||
end,
|
||||
case PacketMod:try_decode_packet(Dec1, PacketSt) of
|
||||
try_decode_packet(Bin, S) ->
|
||||
decode_crypto(Bin, S).
|
||||
|
||||
decode_crypto(<<>>, #codec{crypto_state = CS, crypto_buf = <<>>} = S) ->
|
||||
%% There is smth in packet buffer
|
||||
decode_packet(<<>>, CS, <<>>, S);
|
||||
decode_crypto(Bin, #codec{crypto_mod = CryptoMod,
|
||||
crypto_state = CryptoSt,
|
||||
crypto_buf = <<>>} = S) ->
|
||||
case CryptoMod:try_decode_packet(Bin, CryptoSt) of
|
||||
{incomplete, CryptoSt1} ->
|
||||
decode_packet(<<>>, CryptoSt1, <<>>, S);
|
||||
{ok, Dec1, Tail1, CryptoSt1} ->
|
||||
decode_packet(Dec1, CryptoSt1, Tail1, S)
|
||||
end;
|
||||
decode_crypto(Bin, #codec{crypto_buf = Buf} = S) ->
|
||||
decode_crypto(<<Buf/binary, Bin/binary>>, S#codec{crypto_buf = <<>>}).
|
||||
|
||||
|
||||
decode_packet(<<>>, CryptoSt, CryptoTail, #codec{packet_buf = <<>>} = S) ->
|
||||
%% Crypto produced nothing and there is nothing in packet buf
|
||||
{incomplete, S#codec{crypto_state = CryptoSt, crypto_buf = CryptoTail}};
|
||||
decode_packet(Bin, CryptoSt, CryptoTail, #codec{packet_mod = PacketMod,
|
||||
packet_state = PacketSt,
|
||||
packet_buf = <<>>} = S) ->
|
||||
%% Crypto produced smth, and there is nothing in pkt buf
|
||||
case PacketMod:try_decode_packet(Bin, PacketSt) of
|
||||
{incomplete, PacketSt1} ->
|
||||
{incomplete, S#codec{crypto_state = CryptoSt1,
|
||||
packet_state = PacketSt1}};
|
||||
{ok, Dec2, PacketSt1} ->
|
||||
{ok, Dec2, S#codec{crypto_state = CryptoSt1,
|
||||
packet_state = PacketSt1}}
|
||||
end.
|
||||
{incomplete, S#codec{crypto_state = CryptoSt,
|
||||
crypto_buf = CryptoTail,
|
||||
packet_state = PacketSt1,
|
||||
packet_buf = Bin
|
||||
}};
|
||||
{ok, Dec2, Tail, PacketSt1} ->
|
||||
{ok, Dec2, S#codec{crypto_state = CryptoSt,
|
||||
crypto_buf = CryptoTail,
|
||||
packet_state = PacketSt1,
|
||||
packet_buf = Tail}}
|
||||
end;
|
||||
decode_packet(Bin, CSt, CTail, #codec{packet_buf = Buf} = S) ->
|
||||
decode_packet(<<Buf/binary, Bin/binary>>, CSt, CTail, S#codec{packet_buf = <<>>}).
|
||||
|
||||
|
||||
%% encode_packet(Outer) |> encode_packet(Inner)
|
||||
-spec encode_packet(iodata(), codec()) -> {iodata(), codec()}.
|
||||
|
|
@ -105,3 +130,7 @@ fold_packets(Fun, FoldSt, Data, Codec) ->
|
|||
{incomplete, Codec1} ->
|
||||
{ok, FoldSt, Codec1}
|
||||
end.
|
||||
|
||||
-spec is_empty(codec()) -> boolean().
|
||||
is_empty(#codec{packet_buf = <<>>, crypto_buf = <<>>}) -> true;
|
||||
is_empty(_) -> false.
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@
|
|||
-dialyzer(no_improper_lists).
|
||||
|
||||
-record(full_st,
|
||||
{decode_buf = <<>> :: binary(),
|
||||
enc_seq_no :: integer(),
|
||||
{enc_seq_no :: integer(),
|
||||
dec_seq_no :: integer()}).
|
||||
-define(MIN_MSG_LEN, 12).
|
||||
-define(MAX_MSG_LEN, 16777216). %2^24 - 16mb
|
||||
|
|
@ -39,11 +38,8 @@ new(EncSeqNo, DecSeqNo) ->
|
|||
#full_st{enc_seq_no = EncSeqNo,
|
||||
dec_seq_no = DecSeqNo}.
|
||||
|
||||
try_decode_packet(<<4:32/little, Bin/binary>>, #full_st{decode_buf = <<>>} = S) ->
|
||||
%% Skip padding
|
||||
try_decode_packet(Bin, S);
|
||||
try_decode_packet(<<Len:32/little, PktSeqNo:32/signed-little, Tail/binary>> = Bin,
|
||||
#full_st{decode_buf = <<>>, dec_seq_no = SeqNo} = S) ->
|
||||
try_decode_packet(<<Len:32/little, PktSeqNo:32/signed-little, Tail/binary>>,
|
||||
#full_st{dec_seq_no = SeqNo} = S) ->
|
||||
((Len rem byte_size(?PAD)) == 0)
|
||||
orelse error({wrong_alignement, Len}),
|
||||
((?MIN_MSG_LEN =< Len) and (Len =< ?MAX_MSG_LEN))
|
||||
|
|
@ -56,14 +52,18 @@ try_decode_packet(<<Len:32/little, PktSeqNo:32/signed-little, Tail/binary>> = Bi
|
|||
PacketCrc = erlang:crc32([<<Len:32/little, PktSeqNo:32/little>> | Body]),
|
||||
(CRC == PacketCrc)
|
||||
orelse error({wrong_checksum, CRC, PacketCrc}),
|
||||
{ok, Body, S#full_st{decode_buf = Rest, dec_seq_no = SeqNo + 1}};
|
||||
{ok, Body, skip_padding(Len, Rest), S#full_st{dec_seq_no = SeqNo + 1}};
|
||||
_ ->
|
||||
{incomplete, S#full_st{decode_buf = Bin}}
|
||||
{incomplete, S}
|
||||
end;
|
||||
try_decode_packet(Bin, #full_st{decode_buf = Buf} = S) when byte_size(Buf) > 0 ->
|
||||
try_decode_packet(<<Buf/binary, Bin/binary>>, S#full_st{decode_buf = <<>>});
|
||||
try_decode_packet(Bin, #full_st{decode_buf = <<>>} = S) ->
|
||||
{incomplete, S#full_st{decode_buf = Bin}}.
|
||||
try_decode_packet(_, S) ->
|
||||
{incomplete, S}.
|
||||
|
||||
skip_padding(PktLen, Bin) ->
|
||||
PaddingSize = padding_size(PktLen),
|
||||
<<_:PaddingSize/binary, Tail/binary>> = Bin,
|
||||
Tail.
|
||||
|
||||
|
||||
encode_packet(Bin, #full_st{enc_seq_no = SeqNo} = S) ->
|
||||
BodySize = iolist_size(Bin),
|
||||
|
|
@ -77,12 +77,14 @@ encode_packet(Bin, #full_st{enc_seq_no = SeqNo} = S) ->
|
|||
CheckSum = erlang:crc32(MsgNoChecksum),
|
||||
FullMsg = [MsgNoChecksum | <<CheckSum:32/unsigned-little-integer>>],
|
||||
Len = iolist_size(FullMsg),
|
||||
%% XXX: is there a cleaner way?
|
||||
PaddingSize = (?BLOCK_SIZE - (Len rem ?BLOCK_SIZE)) rem ?BLOCK_SIZE,
|
||||
NPaddings = PaddingSize div byte_size(?PAD),
|
||||
NPaddings = padding_size(Len) div byte_size(?PAD),
|
||||
Padding = lists:duplicate(NPaddings, ?PAD),
|
||||
{[FullMsg | Padding], S#full_st{enc_seq_no = SeqNo + 1}}.
|
||||
|
||||
padding_size(Len) ->
|
||||
%% XXX: is there a cleaner way?
|
||||
(?BLOCK_SIZE - (Len rem ?BLOCK_SIZE)) rem ?BLOCK_SIZE.
|
||||
|
||||
|
||||
-ifdef(TEST).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
|
@ -132,6 +134,7 @@ decode_none_test() ->
|
|||
{incomplete, S}, try_decode_packet(<<>>, S)).
|
||||
|
||||
codec_test() ->
|
||||
%% Overhead is 12b per-packet
|
||||
S = new(),
|
||||
Packets = [
|
||||
binary:copy(<<0>>, 4), %non-padded
|
||||
|
|
@ -143,7 +146,7 @@ codec_test() ->
|
|||
fun(B, S1) ->
|
||||
{Encoded, S2} = encode_packet(B, S1),
|
||||
BinEncoded = iolist_to_binary(Encoded),
|
||||
{ok, Decoded, S3} = try_decode_packet(BinEncoded, S2),
|
||||
{ok, Decoded, <<>>, S3} = try_decode_packet(BinEncoded, S2),
|
||||
?assertEqual(B, Decoded, {BinEncoded, S2, S3}),
|
||||
S3
|
||||
end, S, Packets).
|
||||
|
|
@ -164,9 +167,9 @@ codec_stream_test() ->
|
|||
end, {[], S}, Packets),
|
||||
lists:foldl(
|
||||
fun(B, {Enc, S1}) ->
|
||||
{ok, Dec, S2} = try_decode_packet(Enc, S1),
|
||||
{ok, Dec, Rest, S2} = try_decode_packet(Enc, S1),
|
||||
?assertEqual(B, Dec),
|
||||
{<<>>, S2}
|
||||
{Rest, S2}
|
||||
end, {iolist_to_binary(Encoded), SS}, Packets).
|
||||
|
||||
-endif.
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@
|
|||
-dialyzer(no_improper_lists).
|
||||
|
||||
-record(int_st,
|
||||
{padding = false :: boolean(),
|
||||
buffer = <<>> :: binary()}).
|
||||
{padding = false :: boolean()}).
|
||||
-define(MAX_PACKET_SIZE, 1 * 1024 * 1024). % 1mb
|
||||
-define(APP, mtproto_proxy).
|
||||
-define(MAX_SIZE, 16#80000000).
|
||||
|
|
@ -32,10 +31,9 @@ new() ->
|
|||
new(Opts) ->
|
||||
#int_st{padding = maps:get(padding, Opts, false)}.
|
||||
|
||||
-spec try_decode_packet(binary(), codec()) -> {ok, binary(), codec()}
|
||||
-spec try_decode_packet(binary(), codec()) -> {ok, binary(), binary(), codec()}
|
||||
| {incomplete, codec()}.
|
||||
try_decode_packet(<<Len:32/unsigned-little, _/binary>> = Data,
|
||||
#int_st{buffer = <<>>} = St) ->
|
||||
try_decode_packet(<<Len:32/unsigned-little, Tail/binary>>, St) ->
|
||||
Len1 = case Len < ?MAX_SIZE of
|
||||
true -> Len;
|
||||
false -> Len - ?MAX_SIZE
|
||||
|
|
@ -45,11 +43,9 @@ try_decode_packet(<<Len:32/unsigned-little, _/binary>> = Data,
|
|||
begin
|
||||
error({protocol_error, intermediate_max_size, Len1})
|
||||
end,
|
||||
try_decode_packet_len(Len1, Data, St);
|
||||
try_decode_packet(Bin, #int_st{buffer = Buf} = St) when byte_size(Buf) > 0 ->
|
||||
try_decode_packet(<<Buf/binary, Bin/binary>>, St#int_st{buffer = <<>>});
|
||||
try_decode_packet(Bin, #int_st{buffer = <<>>} = St) ->
|
||||
{incomplete, St#int_st{buffer = Bin}}.
|
||||
try_decode_packet_len(Len1, Tail, St);
|
||||
try_decode_packet(_, St) ->
|
||||
{incomplete, St}.
|
||||
|
||||
try_decode_packet_len(Len, Data, #int_st{padding = Pad} = St) ->
|
||||
Padding = case Pad of
|
||||
|
|
@ -58,10 +54,10 @@ try_decode_packet_len(Len, Data, #int_st{padding = Pad} = St) ->
|
|||
end,
|
||||
NopadLen = Len - Padding,
|
||||
case Data of
|
||||
<<_:4/binary, Packet:NopadLen/binary, _Padding:Padding/binary, Rest/binary>> ->
|
||||
{ok, Packet, St#int_st{buffer = Rest}};
|
||||
<<Packet:NopadLen/binary, _Padding:Padding/binary, Rest/binary>> ->
|
||||
{ok, Packet, Rest, St};
|
||||
_ ->
|
||||
{incomplete, St#int_st{buffer = Data}}
|
||||
{incomplete, St}
|
||||
end.
|
||||
|
||||
-spec encode_packet(iodata(), codec()) -> {iodata(), codec()}.
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@
|
|||
new() ->
|
||||
?MODULE.
|
||||
|
||||
-spec try_decode_packet(binary(), codec()) -> {ok, binary(), codec()}.
|
||||
-spec try_decode_packet(binary(), codec()) -> {ok, binary(), binary(), codec()}.
|
||||
try_decode_packet(Data, ?MODULE) ->
|
||||
{ok, Data, ?MODULE}.
|
||||
{ok, Data, <<>>, ?MODULE}.
|
||||
|
||||
-spec encode_packet(binary(), codec()) -> {binary(), codec()}.
|
||||
encode_packet(Data, ?MODULE) ->
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ from_header(Header, Secret, AllowedProtocols) when byte_size(Header) == 64 ->
|
|||
{EncKey, EncIV} = init_up_encrypt(Header, Secret),
|
||||
{DecKey, DecIV} = init_up_decrypt(Header, Secret),
|
||||
St = new(EncKey, EncIV, DecKey, DecIV),
|
||||
{<<_:56/binary, Bin1:6/binary, _:2/binary>>, St1} = decrypt(Header, St),
|
||||
{<<_:56/binary, Bin1:6/binary, _:2/binary>>, <<>>, St1} = decrypt(Header, St),
|
||||
case get_protocol(Bin1) of
|
||||
{error, unknown_protocol} = Err ->
|
||||
Err;
|
||||
|
|
@ -168,17 +168,17 @@ encrypt(Data, #st{encrypt = Enc} = St) ->
|
|||
{Enc1, Encrypted} = crypto:stream_encrypt(Enc, Data),
|
||||
{Encrypted, St#st{encrypt = Enc1}}.
|
||||
|
||||
-spec decrypt(iodata(), codec()) -> {binary(), codec()}.
|
||||
-spec decrypt(iodata(), codec()) -> {binary(), binary(), codec()}.
|
||||
decrypt(Encrypted, #st{decrypt = Dec} = St) ->
|
||||
{Dec1, Data} = crypto:stream_encrypt(Dec, Encrypted),
|
||||
{Data, St#st{decrypt = Dec1}}.
|
||||
{Data, <<>>, St#st{decrypt = Dec1}}.
|
||||
|
||||
%% To comply with mtp_layer interface
|
||||
-spec try_decode_packet(iodata(), codec()) -> {ok, Decoded :: binary(), codec()}
|
||||
-spec try_decode_packet(iodata(), codec()) -> {ok, Decoded :: binary(), Tail :: binary(), codec()}
|
||||
| {incomplete, codec()}.
|
||||
try_decode_packet(Encrypted, St) ->
|
||||
{Decrypted, St1} = decrypt(Encrypted, St),
|
||||
{ok, Decrypted, St1}.
|
||||
{Decrypted, Tail, St1} = decrypt(Encrypted, St),
|
||||
{ok, Decrypted, Tail, St1}.
|
||||
|
||||
-spec encode_packet(iodata(), codec()) -> {iodata(), codec()}.
|
||||
encode_packet(Msg, S) ->
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
new() ->
|
||||
mtp_intermediate:new(#{padding => true}).
|
||||
|
||||
-spec try_decode_packet(binary(), codec()) -> {ok, binary(), codec()}
|
||||
-spec try_decode_packet(binary(), codec()) -> {ok, binary(), binary(), codec()}
|
||||
| {incomplete, codec()}.
|
||||
try_decode_packet(Data, St) ->
|
||||
mtp_intermediate:try_decode_packet(Data, St).
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ prop_codec() ->
|
|||
codec(Bin) ->
|
||||
Codec = mtp_abridged:new(),
|
||||
{Data, Codec1} = mtp_abridged:encode_packet(Bin, Codec),
|
||||
{ok, Decoded, _} = mtp_abridged:try_decode_packet(iolist_to_binary(Data), Codec1),
|
||||
{ok, Decoded, <<>>, _} = mtp_abridged:try_decode_packet(iolist_to_binary(Data), Codec1),
|
||||
Decoded == Bin.
|
||||
|
||||
|
||||
|
|
@ -39,6 +39,6 @@ decode_stream(BinStream, Codec, Acc) ->
|
|||
case mtp_abridged:try_decode_packet(BinStream, Codec) of
|
||||
{incomplete, _} ->
|
||||
lists:reverse(Acc);
|
||||
{ok, DecPacket, Codec1} ->
|
||||
decode_stream(<<>>, Codec1, [DecPacket | Acc])
|
||||
{ok, DecPacket, Tail, Codec1} ->
|
||||
decode_stream(Tail, Codec1, [DecPacket | Acc])
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,6 @@ stream_codec(Key, Iv, Stream) ->
|
|||
{<<Acc/binary, (iolist_to_binary(Data))/binary>>,
|
||||
Codec2}
|
||||
end, {<<>>, Codec}, Stream),
|
||||
{Decrypted, _Codec3} = mtp_aes_cbc:decrypt(BinStream, Codec2),
|
||||
{Decrypted, <<>>, _Codec3} = mtp_aes_cbc:decrypt(BinStream, Codec2),
|
||||
%% io:format("Dec: ~p~nOrig: ~p~nCodec: ~p~n", [Decrypted, Stream, _Codec3]),
|
||||
Decrypted == iolist_to_binary(Stream).
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ prop_codec() ->
|
|||
codec(Bin) ->
|
||||
Codec = mtp_full:new(),
|
||||
{Data, Codec1} = mtp_full:encode_packet(Bin, Codec),
|
||||
{ok, Decoded, _} = mtp_full:try_decode_packet(iolist_to_binary(Data), Codec1),
|
||||
{ok, Decoded, <<>>, _} = mtp_full:try_decode_packet(iolist_to_binary(Data), Codec1),
|
||||
Decoded == Bin.
|
||||
|
||||
|
||||
|
|
@ -40,6 +40,6 @@ decode_stream(BinStream, Codec, Acc) ->
|
|||
case mtp_full:try_decode_packet(BinStream, Codec) of
|
||||
{incomplete, _} ->
|
||||
lists:reverse(Acc);
|
||||
{ok, DecPacket, Codec1} ->
|
||||
decode_stream(<<>>, Codec1, [DecPacket | Acc])
|
||||
{ok, DecPacket, Tail, Codec1} ->
|
||||
decode_stream(Tail, Codec1, [DecPacket | Acc])
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ prop_codec() ->
|
|||
codec(Bin) ->
|
||||
Codec = mtp_intermediate:new(),
|
||||
{Data, Codec1} = mtp_intermediate:encode_packet(Bin, Codec),
|
||||
{ok, Decoded, _} = mtp_intermediate:try_decode_packet(iolist_to_binary(Data), Codec1),
|
||||
{ok, Decoded, <<>>, _} = mtp_intermediate:try_decode_packet(iolist_to_binary(Data), Codec1),
|
||||
Decoded == Bin.
|
||||
|
||||
|
||||
|
|
@ -40,8 +40,8 @@ decode_stream(BinStream, Codec, Acc) ->
|
|||
case mtp_intermediate:try_decode_packet(BinStream, Codec) of
|
||||
{incomplete, _} ->
|
||||
lists:reverse(Acc);
|
||||
{ok, DecPacket, Codec1} ->
|
||||
decode_stream(<<>>, Codec1, [DecPacket | Acc])
|
||||
{ok, DecPacket, Tail, Codec1} ->
|
||||
decode_stream(Tail, Codec1, [DecPacket | Acc])
|
||||
end.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ stream_codec(Key, Iv, Stream) ->
|
|||
{<<Acc/binary, (iolist_to_binary(Data))/binary>>,
|
||||
Codec2}
|
||||
end, {<<>>, Codec}, Stream),
|
||||
{Decrypted, _Codec3} = mtp_obfuscated:decrypt(BinStream, Codec2),
|
||||
{Decrypted, <<>>, _Codec3} = mtp_obfuscated:decrypt(BinStream, Codec2),
|
||||
%% io:format("Dec: ~p~nOrig: ~p~nCodec: ~p~n", [Decrypted, Stream, _Codec3]),
|
||||
Decrypted == iolist_to_binary(Stream).
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ transmit_stream(EncCodec, DecCodec, Stream) ->
|
|||
{<<Acc/binary, (iolist_to_binary(Data))/binary>>,
|
||||
CliCodec2}
|
||||
end, {<<>>, EncCodec}, Stream),
|
||||
{Decrypted, DecCodec2} = mtp_obfuscated:decrypt(EncStream, DecCodec),
|
||||
{Decrypted, <<>>, DecCodec2} = mtp_obfuscated:decrypt(EncStream, DecCodec),
|
||||
{EncCodec3,
|
||||
DecCodec2,
|
||||
Decrypted}.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue