aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src/tls_record.erl
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2019-02-08 11:41:27 +0100
committerRaimo Niskanen <[email protected]>2019-02-13 14:18:23 +0100
commit96cd83b6efed8ae8a1a0008e24885bae66c1834b (patch)
tree56097aece57096bf7fc9e0d485ecbe4a5e0b627b /lib/ssl/src/tls_record.erl
parent38ce21e37be4578a7a89856ddb91516279e58c13 (diff)
downloadotp-96cd83b6efed8ae8a1a0008e24885bae66c1834b.tar.gz
otp-96cd83b6efed8ae8a1a0008e24885bae66c1834b.tar.bz2
otp-96cd83b6efed8ae8a1a0008e24885bae66c1834b.zip
Use iovec() internally in send path
Diffstat (limited to 'lib/ssl/src/tls_record.erl')
-rw-r--r--lib/ssl/src/tls_record.erl78
1 files changed, 46 insertions, 32 deletions
diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl
index e68f9a19df..7d1f2f5e92 100644
--- a/lib/ssl/src/tls_record.erl
+++ b/lib/ssl/src/tls_record.erl
@@ -105,8 +105,8 @@ encode_handshake(Frag, Version,
ConnectionStates) ->
case iolist_size(Frag) of
N when N > ?MAX_PLAIN_TEXT_LENGTH ->
- Data = split_bin(iolist_to_binary(Frag), Version, BCA, BeastMitigation),
- encode_iolist(?HANDSHAKE, Version, Data, ConnectionStates);
+ Data = split_iovec(erlang:iolist_to_iovec(Frag), Version, BCA, BeastMitigation),
+ encode_fragments(?HANDSHAKE, Version, Data, ConnectionStates);
_ ->
encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates)
end.
@@ -137,13 +137,13 @@ encode_change_cipher_spec(Version, ConnectionStates) ->
%%
%% Description: Encodes data to send on the ssl-socket.
%%--------------------------------------------------------------------
-encode_data(Frag, Version,
+encode_data(Data, Version,
#{current_write := #{beast_mitigation := BeastMitigation,
security_parameters :=
#security_parameters{bulk_cipher_algorithm = BCA}}} =
ConnectionStates) ->
- Data = split_bin(Frag, Version, BCA, BeastMitigation),
- encode_iolist(?APPLICATION_DATA, Version, Data, ConnectionStates).
+ Fragments = split_iovec(Data, Version, BCA, BeastMitigation),
+ encode_fragments(?APPLICATION_DATA, Version, Fragments, ConnectionStates).
%%====================================================================
%% Decoding
@@ -520,22 +520,22 @@ binary_from_front(BinSize, [Bin|Front], Size, Rear, Acc) ->
%%--------------------------------------------------------------------
encode_plain_text(Type, Version, Data, ConnectionStates0) ->
- {[CipherText],ConnectionStates} = encode_iolist(Type, Version, [Data], ConnectionStates0),
+ {[CipherText],ConnectionStates} = encode_fragments(Type, Version, [Data], ConnectionStates0),
{CipherText,ConnectionStates}.
%%--------------------------------------------------------------------
-encode_iolist(Type, Version, Data,
+encode_fragments(Type, Version, Data,
#{current_write := #{compression_state := CompS,
cipher_state := CipherS,
sequence_number := Seq}} = ConnectionStates) ->
- encode_iolist(Type, Version, Data, ConnectionStates, CompS, CipherS, Seq, []).
+ encode_fragments(Type, Version, Data, ConnectionStates, CompS, CipherS, Seq, []).
%%
-encode_iolist(_Type, _Version, [], #{current_write := WriteS} = CS,
+encode_fragments(_Type, _Version, [], #{current_write := WriteS} = CS,
CompS, CipherS, Seq, CipherFragments) ->
{lists:reverse(CipherFragments),
CS#{current_write := WriteS#{compression_state := CompS,
cipher_state := CipherS,
sequence_number := Seq}}};
-encode_iolist(Type, Version, [Text|Data],
+encode_fragments(Type, Version, [Text|Data],
#{current_write := #{security_parameters :=
#security_parameters{cipher_type = ?AEAD,
bulk_cipher_algorithm = BCAlg,
@@ -550,9 +550,9 @@ encode_iolist(Type, Version, [Text|Data],
{CipherFragment,CipherS} = ssl_record:cipher_aead(Version, CompText, CipherS1, StartAdditionalData, SecPars),
Length = byte_size(CipherFragment),
CipherHeader = <<?BYTE(Type), VersionBin/binary, ?UINT16(Length)>>,
- encode_iolist(Type, Version, Data, CS, CompS, CipherS, Seq + 1,
+ encode_fragments(Type, Version, Data, CS, CompS, CipherS, Seq + 1,
[[CipherHeader, CipherFragment] | CipherFragments]);
-encode_iolist(Type, Version, [Text|Data],
+encode_fragments(Type, Version, [Text|Data],
#{current_write := #{security_parameters :=
#security_parameters{compression_algorithm = CompAlg,
mac_algorithm = MacAlgorithm} = SecPars,
@@ -564,35 +564,49 @@ encode_iolist(Type, Version, [Text|Data],
Length = byte_size(CipherFragment),
{MajVer, MinVer} = Version,
CipherHeader = <<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Length)>>,
- encode_iolist(Type, Version, Data, CS, CompS, CipherS, Seq + 1,
+ encode_fragments(Type, Version, Data, CS, CompS, CipherS, Seq + 1,
[[CipherHeader, CipherFragment] | CipherFragments]);
-encode_iolist(_Type, _Version, _Data, CS, _CompS, _CipherS, _Seq, _CipherFragments) ->
+encode_fragments(_Type, _Version, _Data, CS, _CompS, _CipherS, _Seq, _CipherFragments) ->
exit({cs, CS}).
%%--------------------------------------------------------------------
%% 1/n-1 splitting countermeasure Rizzo/Duong-Beast, RC4 chiphers are
%% not vulnerable to this attack.
-split_bin(<<FirstByte:8, Rest/binary>>, Version, BCA, one_n_minus_one) when
- BCA =/= ?RC4 andalso ({3, 1} == Version orelse
- {3, 0} == Version) ->
- [[FirstByte]|do_split_bin(Rest)];
+split_iovec([<<FirstByte:8, Rest/binary>>|Data], Version, BCA, one_n_minus_one)
+ when (BCA =/= ?RC4) andalso ({3, 1} == Version orelse
+ {3, 0} == Version) ->
+ [[FirstByte]|split_iovec([Rest|Data])];
%% 0/n splitting countermeasure for clients that are incompatible with 1/n-1
%% splitting.
-split_bin(Bin, Version, BCA, zero_n) when
- BCA =/= ?RC4 andalso ({3, 1} == Version orelse
- {3, 0} == Version) ->
- [<<>>|do_split_bin(Bin)];
-split_bin(Bin, _, _, _) ->
- do_split_bin(Bin).
-
-do_split_bin(<<>>) -> [];
-do_split_bin(Bin) ->
+split_iovec(Data, Version, BCA, zero_n)
+ when (BCA =/= ?RC4) andalso ({3, 1} == Version orelse
+ {3, 0} == Version) ->
+ [<<>>|split_iovec(Data)];
+split_iovec(Data, _Version, _BCA, _BeatMitigation) ->
+ split_iovec(Data).
+
+split_iovec([]) ->
+ [];
+split_iovec(Data) ->
+ {Part,Rest} = split_iovec(Data, ?MAX_PLAIN_TEXT_LENGTH, []),
+ [Part|split_iovec(Rest)].
+%%
+split_iovec([Bin|Data], Size, Acc) ->
case Bin of
- <<Chunk:?MAX_PLAIN_TEXT_LENGTH/binary, Rest/binary>> ->
- [Chunk|do_split_bin(Rest)];
- _ ->
- [Bin]
- end.
+ <<Last:Size/binary, Rest/binary>> ->
+ {lists:reverse(Acc, [Last]),
+ case Rest of
+ <<>> ->
+ Data;
+ <<_/binary>> ->
+ [Rest|Data]
+ end};
+ <<_/binary>> ->
+ split_iovec(Data, Size - byte_size(Bin), [Bin|Acc])
+ end;
+split_iovec([], _Size, Acc) ->
+ {lists:reverse(Acc),[]}.
+
%%--------------------------------------------------------------------
lowest_list_protocol_version(Ver, []) ->
Ver;