File 4145-Simplify-input_handler.patch of Package erlang
From c3a78dc081601d6b0818537ce963fa5ec6b979d9 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Fri, 21 Oct 2022 18:45:06 +0200
Subject: [PATCH 25/27] Simplify input_handler
---
lib/ssl/test/inet_crypto_dist.erl | 215 +++++++++++++++---------------
1 file changed, 111 insertions(+), 104 deletions(-)
diff --git a/lib/ssl/test/inet_crypto_dist.erl b/lib/ssl/test/inet_crypto_dist.erl
index 9e461ac185..b9a7e5ba1f 100644
--- a/lib/ssl/test/inet_crypto_dist.erl
+++ b/lib/ssl/test/inet_crypto_dist.erl
@@ -1364,120 +1364,127 @@ output_handler_xfer(Params, Seq, Front, Size, Rear) ->
%%
input_handler(Params, Seq) ->
- input_handler(Params, Seq, [], 0, []).
+ %% Shortcut into the loop
+ {Params_1, Seq_1, Data} = input_data(Params, Seq),
+ input_handler(Params_1, Seq_1, Data, [], byte_size(Data)).
%%
-input_handler(#params{socket = Socket} = Params, Seq, Front, Size, Rear) ->
- receive
- Msg ->
- case Msg of
- {tcp_passive, Socket} ->
- ok = inet:setopts(Socket, [{active, ?TCP_ACTIVE}]),
- input_handler(Params, Seq, Front, Size, Rear);
- {tcp, Socket, Chunk} ->
- input_chunk(Params, Seq, Front, Size, Rear, Chunk);
- {tcp_closed, Socket} ->
- error_logger:info_report(
- [?FUNCTION_NAME,
- {reason, tcp_closed}]),
- exit(connection_closed);
- Other ->
- %% Ignore...
- _ = trace(Other),
- input_handler(Params, Seq, Front, Size, Rear)
- end
- end.
-
-input_chunk(Params, Seq, Front, Size, Rear, Chunk) ->
- case decrypt_chunk(Params, Seq, Chunk) of
- <<?DATA_CHUNK, Cleartext/binary>> ->
- input_deliver(
- Params, Seq + 1, Front,
- Size + byte_size(Cleartext), [Cleartext|Rear]);
- <<?TICK_CHUNK, _/binary>> ->
- input_handler(Params, Seq + 1, Front, Size, Rear);
- UnknownChunk when is_binary(UnknownChunk) ->
- error_logger:error_report(
- [?FUNCTION_NAME,
- {reason, unknown_chunk}]),
- _ = trace(invalid_chunk),
- exit(connection_closed);
- #params{} = Params_1 ->
- input_handler(Params_1, 0, Front, Size, Rear);
- error ->
- _ = trace(decrypt_error),
- exit(connection_closed)
- end.
-
-input_deliver(Params, Seq, [], Size, []) ->
- Size = 0, % Assert
- input_handler(Params, Seq, [], Size, []);
-input_deliver(Params, Seq, [], Size, Rear) ->
- [Bin|Front] = lists:reverse(Rear),
- input_deliver(Params, Seq, Front, Size, [], Bin);
-input_deliver(Params, Seq, [Bin|Front], Size, Rear) ->
- input_deliver(Params, Seq, Front, Size, Rear, Bin).
-%%
-input_deliver(Params, Seq, Front, Size, Rear, Bin) ->
- case Bin of
- <<DataSizeA:32, DataA:DataSizeA/binary,
- DataSizeB:32, DataB:DataSizeB/binary, Rest/binary>> ->
+input_handler(Params, Seq, First, Buffer, Size) ->
+ %% Size is size of First + Buffer
+ case First of
+ <<Packet1Size:32, Packet1:Packet1Size/binary,
+ Packet2Size:32, Packet2:Packet2Size/binary, Rest/binary>> ->
DistHandle = Params#params.dist_handle,
- erlang:dist_ctrl_put_data(DistHandle, DataA),
- erlang:dist_ctrl_put_data(DistHandle, DataB),
- input_deliver(
- Params, Seq,
- Front, Size - (4 + DataSizeA + 4 + DataSizeB), Rear,
- Rest);
- <<DataSize:32, Data:DataSize/binary, Rest/binary>> ->
+ erlang:dist_ctrl_put_data(DistHandle, Packet1),
+ erlang:dist_ctrl_put_data(DistHandle, Packet2),
+ input_handler(
+ Params, Seq, Rest,
+ Buffer, Size - (8 + Packet1Size + Packet2Size));
+ <<PacketSize:32, Packet:PacketSize/binary, Rest/binary>> ->
DistHandle = Params#params.dist_handle,
- erlang:dist_ctrl_put_data(DistHandle, Data),
- input_deliver(
- Params, Seq,
- Front, Size - (4 + DataSize), Rear,
- Rest);
- <<DataSize:32, FirstData/binary>> ->
- %% We do not have a complete packet in the first binary
- TotalSize = 4 + DataSize,
- if
- TotalSize =< Size ->
- %% We have a complete packet queued
- BinSize = byte_size(Bin),
- {MoreData, Q} =
- deq_iovec(
- TotalSize - BinSize,
- Front, Size - BinSize, Rear),
- DistHandle = Params#params.dist_handle,
- erlang:dist_ctrl_put_data(
- DistHandle, [FirstData|MoreData]),
- input_deliver(Params, Seq, Q);
- true ->
- %% We an incomplete packet
- input_handler(Params, Seq, [Bin|Front], Size, Rear)
- end;
- <<_/binary>> ->
- %% We do not have a size header in the first binary
- BinSize = byte_size(Bin),
+ erlang:dist_ctrl_put_data(DistHandle, Packet),
+ input_handler(
+ Params, Seq, Rest, Buffer, Size - (4 + PacketSize));
+ <<PacketSize:32, PacketStart/binary>> ->
+ %% Partial packet in First
+ input_handler(
+ Params, Seq, PacketStart, Buffer, Size - 4, PacketSize);
+ <<Bin/binary>> ->
+ %% Partial header in First
if
4 =< Size ->
- %% We have a size header queued
- %%
- %% Extract a binary with just the size header
- RestSize = 4 - BinSize,
- {RestHeader, Q} =
- deq_iovec(RestSize, Front, Size + RestSize, Rear),
- Header = iolist_to_binary([Bin|RestHeader]),
- input_deliver(Params, Seq, Q, Header);
+ %% Complete header in First + Buffer
+ {First_1, Buffer_1, PacketSize} =
+ input_get_packet_size(Bin, lists:reverse(Buffer)),
+ input_handler(
+ Params, Seq, First_1, Buffer_1, Size - 4, PacketSize);
true ->
- %% We an incomplete size header
- input_handler(Params, Seq, [Bin|Front], Size, Rear)
+ %% Incomplete header received so far
+ {Params_1, Seq_1, More} = input_data(Params, Seq),
+ input_handler(
+ Params_1, Seq_1, Bin,
+ [More|Buffer], Size + byte_size(More))
end
end.
%%
-input_deliver(Params, Seq, {Front, Size, Rear}) ->
- input_deliver(Params, Seq, Front, Size, Rear).
+input_handler(Params, Seq, PacketStart, Buffer, Size, PacketSize) ->
+ %% Size is size of PacketStart + Buffer
+ RestSize = Size - PacketSize,
+ if
+ RestSize < 0 ->
+ %% Incomplete packet received so far
+ {Params_1, Seq_1, More} = input_data(Params, Seq),
+ input_handler(
+ Params_1, Seq_1, PacketStart,
+ [More|Buffer], Size + byte_size(More), PacketSize);
+ 0 < RestSize, Buffer =:= [] ->
+ %% Rest data in PacketStart
+ <<Packet:PacketSize/binary, Rest/binary>> = PacketStart,
+ DistHandle = Params#params.dist_handle,
+ erlang:dist_ctrl_put_data(DistHandle, Packet),
+ input_handler(Params, Seq, Rest, [], RestSize);
+ Buffer =:= [] -> % RestSize == 0
+ %% No rest data
+ DistHandle = Params#params.dist_handle,
+ erlang:dist_ctrl_put_data(DistHandle, PacketStart),
+ input_handler(Params, Seq);
+ true ->
+ %% Split packet from rest data
+ LastBin = hd(Buffer),
+ <<PacketLast:(byte_size(LastBin) - RestSize)/binary,
+ Rest/binary>> = LastBin,
+ Packet = [PacketStart|lists:reverse(tl(Buffer), PacketLast)],
+ DistHandle = Params#params.dist_handle,
+ erlang:dist_ctrl_put_data(DistHandle, Packet),
+ input_handler(Params, Seq, Rest, [], RestSize)
+ end.
+
+input_get_packet_size(First, [Bin|Buffer]) ->
+ MissingSize = 4 - byte_size(First),
+ if
+ MissingSize =< byte_size(Bin) ->
+ <<Last:MissingSize/binary, Rest/binary>> = Bin,
+ <<PacketSize:32>> = <<First/binary, Last/binary>>,
+ {Rest, lists:reverse(Buffer), PacketSize};
+ true ->
+ input_get_packet_size(<<First/binary, Bin/binary>>, Buffer)
+ end.
+
+input_data(Params, Seq) ->
+ receive Msg -> input_data(Params, Seq, Msg) end.
%%
-input_deliver(Params, Seq, {Front, Size, Rear}, Bin) ->
- input_deliver(Params, Seq, Front, Size, Rear, Bin).
+input_data(#params{socket = Socket} = Params, Seq, Msg) ->
+ case Msg of
+ {tcp_passive, Socket} ->
+ ok = inet:setopts(Socket, [{active, ?TCP_ACTIVE}]),
+ input_data(Params, Seq);
+ {tcp, Socket, Ciphertext} ->
+ case decrypt_chunk(Params, Seq, Ciphertext) of
+ <<?DATA_CHUNK, Chunk/binary>> ->
+ {Params, Seq + 1, Chunk};
+ <<?TICK_CHUNK, _Dummy/binary>> ->
+ input_data(Params, Seq + 1);
+ <<UnknownChunk/binary>> ->
+ error_logger:error_report(
+ [?FUNCTION_NAME,
+ {reason, unknown_chunk}]),
+ _ = trace(UnknownChunk),
+ exit(connection_closed);
+ #params{} = Params_1 ->
+ input_data(Params_1, 0);
+ error ->
+ _ = trace(decrypt_error),
+ exit(connection_closed)
+ end;
+ {tcp_closed = Reason, Socket} ->
+ error_logger:info_report(
+ [?FUNCTION_NAME,
+ {reason, Reason}]),
+ exit(connection_closed);
+ Other ->
+ %% Ignore...
+ _ = trace(Other),
+ input_data(Params, Seq)
+ end.
%% -------------------------------------------------------------------------
%% Encryption and decryption helpers
--
2.35.3