Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
4599-ssl-send-fragmented-dtls-packets-separatel...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 4599-ssl-send-fragmented-dtls-packets-separately.patch of Package erlang
From d448bcb6c284f136835cdef783a25375ddaa4ebd Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson <dgud@erlang.org> Date: Wed, 13 Oct 2021 15:58:16 +0200 Subject: [PATCH 09/10] ssl: send fragmented dtls packets separately Do not undo the fragmentation already done. --- lib/ssl/src/dtls_connection.erl | 10 ++++- lib/ssl/src/dtls_gen_connection.erl | 64 +++++++++++++++++++++-------- lib/ssl/src/dtls_record.erl | 10 +++-- 3 files changed, 62 insertions(+), 22 deletions(-) diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl index 1e2f0eb36a..7c7a1be9d0 100644 --- a/lib/ssl/src/dtls_connection.erl +++ b/lib/ssl/src/dtls_connection.erl @@ -805,7 +805,7 @@ send_application_data(Data, From, _StateName, {Msgs, ConnectionStates} = dtls_record:encode_data(Data, Version, ConnectionStates0), State = State0#state{connection_states = ConnectionStates}, - case dtls_gen_connection:send(Transport, Socket, Msgs) of + case send_msgs(Transport, Socket, Msgs) of ok -> ssl_logger:debug(LogLevel, outbound, 'record', Msgs), ssl_gen_statem:hibernate_after(connection, State, [{reply, From, ok}]); @@ -814,6 +814,14 @@ send_application_data(Data, From, _StateName, end end. +send_msgs(Transport, Socket, [Msg|Msgs]) -> + case dtls_gen_connection:send(Transport, Socket, Msg) of + ok -> send_msgs(Transport, Socket, Msgs); + Error -> Error + end; +send_msgs(_, _, []) -> + ok. + time_to_renegotiate(_Data, #{current_write := #{sequence_number := Num}}, RenegotiateAt) -> diff --git a/lib/ssl/src/dtls_gen_connection.erl b/lib/ssl/src/dtls_gen_connection.erl index 12aa094191..dab05335c0 100644 --- a/lib/ssl/src/dtls_gen_connection.erl +++ b/lib/ssl/src/dtls_gen_connection.erl @@ -68,6 +68,14 @@ send_alert_in_connection/2, close/5, protocol_name/0]). + + +%% See thread @ http://lists.cluenet.de/pipermail/ipv6-ops/2011-June/005755.html +%% 1280 - headers +-define(PMTUEstimate, 1200). + + + %%==================================================================== %% Internal application API %%==================================================================== @@ -244,12 +252,11 @@ send_handshake_flight(#state{static_env = #static_env{socket = Socket, connection_states = ConnectionStates0, ssl_options = #{log_level := LogLevel}} = State0, Epoch) -> - PMTUEstimate = 1400, %% TODO make configurable #{current_write := #{max_fragment_length := MaxFragmentLength}} = ConnectionStates0, - MaxSize = min(MaxFragmentLength, PMTUEstimate), + MaxSize = min(MaxFragmentLength, ?PMTUEstimate), {Encoded, ConnectionStates} = encode_handshake_flight(lists:reverse(Flight), Version, MaxSize, Epoch, ConnectionStates0), - send(Transport, Socket, Encoded), + send_packets(Transport, Socket, Encoded), ssl_logger:debug(LogLevel, outbound, 'record', Encoded), {State0#state{connection_states = ConnectionStates}, []}; @@ -262,14 +269,12 @@ send_handshake_flight(#state{static_env = #static_env{socket = Socket, connection_states = ConnectionStates0, ssl_options = #{log_level := LogLevel}} = State0, Epoch) -> - PMTUEstimate = 1400, %% TODO make configurable #{current_write := #{max_fragment_length := MaxFragmentLength}} = ConnectionStates0, - MaxSize = min(MaxFragmentLength, PMTUEstimate), + MaxSize = min(MaxFragmentLength, ?PMTUEstimate), {HsBefore, ConnectionStates1} = encode_handshake_flight(lists:reverse(Flight0), Version, MaxSize, Epoch, ConnectionStates0), {EncChangeCipher, ConnectionStates} = encode_change_cipher(ChangeCipher, Version, Epoch, ConnectionStates1), - - send(Transport, Socket, [HsBefore, EncChangeCipher]), + send_packets(Transport, Socket, HsBefore ++ EncChangeCipher), ssl_logger:debug(LogLevel, outbound, 'record', [HsBefore]), ssl_logger:debug(LogLevel, outbound, 'record', [EncChangeCipher]), {State0#state{connection_states = ConnectionStates}, []}; @@ -283,16 +288,15 @@ send_handshake_flight(#state{static_env = #static_env{socket = Socket, connection_states = ConnectionStates0, ssl_options = #{log_level := LogLevel}} = State0, Epoch) -> - PMTUEstimate = 1400, %% TODO make configurable #{current_write := #{max_fragment_length := MaxFragmentLength}} = ConnectionStates0, - MaxSize = min(MaxFragmentLength, PMTUEstimate), + MaxSize = min(MaxFragmentLength, ?PMTUEstimate), {HsBefore, ConnectionStates1} = encode_handshake_flight(lists:reverse(Flight0), Version, MaxSize, Epoch-1, ConnectionStates0), {EncChangeCipher, ConnectionStates2} = encode_change_cipher(ChangeCipher, Version, Epoch-1, ConnectionStates1), {HsAfter, ConnectionStates} = encode_handshake_flight(lists:reverse(Flight1), Version, MaxSize, Epoch, ConnectionStates2), - send(Transport, Socket, [HsBefore, EncChangeCipher, HsAfter]), + send_packets(Transport, Socket, HsBefore ++ EncChangeCipher ++ HsAfter), ssl_logger:debug(LogLevel, outbound, 'record', [HsBefore]), ssl_logger:debug(LogLevel, outbound, 'record', [EncChangeCipher]), ssl_logger:debug(LogLevel, outbound, 'record', [HsAfter]), @@ -307,14 +311,13 @@ send_handshake_flight(#state{static_env = #static_env{socket = Socket, connection_states = ConnectionStates0, ssl_options = #{log_level := LogLevel}} = State0, Epoch) -> - PMTUEstimate = 1400, %% TODO make configurable #{current_write := #{max_fragment_length := MaxFragmentLength}} = ConnectionStates0, - MaxSize = min(MaxFragmentLength, PMTUEstimate), + MaxSize = min(MaxFragmentLength, ?PMTUEstimate), {EncChangeCipher, ConnectionStates1} = encode_change_cipher(ChangeCipher, Version, Epoch-1, ConnectionStates0), {HsAfter, ConnectionStates} = encode_handshake_flight(lists:reverse(Flight1), Version, MaxSize, Epoch, ConnectionStates1), - send(Transport, Socket, [EncChangeCipher, HsAfter]), + send_packets(Transport, Socket, EncChangeCipher ++ HsAfter), ssl_logger:debug(LogLevel, outbound, 'record', [EncChangeCipher]), ssl_logger:debug(LogLevel, outbound, 'record', [HsAfter]), {State0#state{connection_states = ConnectionStates}, []}. @@ -479,6 +482,28 @@ send(Transport, {Listener, Socket}, Data) when is_pid(Listener) -> send(Transport, Socket, Data) -> % Client socket dtls_socket:send(Transport, Socket, Data). +send_packets(_Transport, _Socket, []) -> + ok; +send_packets(Transport, Socket, Packets) -> + {Packet, Rest} = pack_packets(Packets, 0, ?PMTUEstimate+80, []), + case send(Transport, Socket, Packet) of + ok -> send_packets(Transport, Socket, Rest); + Err -> Err + end. + +pack_packets([P|Rest]=Packets, SoFar, Max, Acc) -> + Size = erlang:iolist_size(P), + Next = SoFar + Size, + if Size > Max, Acc =:= [] -> + {P, Rest}; + Next < Max -> + pack_packets(Rest, Next, Max, [P|Acc]); + true -> + {lists:reverse(Acc), Packets} + end; +pack_packets([], _, _, Acc) -> + {lists:reverse(Acc), []}. + socket(Pid, Transport, Socket, _Tracker) -> dtls_socket:socket(Pid, Transport, Socket, ?MODULE). @@ -577,10 +602,15 @@ unprocessed_events(Events) -> erlang:length(Events)-1. encode_handshake_flight(Flight, Version, MaxFragmentSize, Epoch, ConnectionStates) -> - Fragments = lists:map(fun(Handshake) -> - dtls_handshake:fragment_handshake(Handshake, MaxFragmentSize) - end, Flight), - dtls_record:encode_handshake(Fragments, Version, Epoch, ConnectionStates). + Encode = fun(Fragment, {Acc, Cs0}) -> + {Enc, Cs} = dtls_record:encode_handshake(Fragment, Version, Epoch, Cs0), + {[Enc|Acc], Cs} + end, + {Rev, Cs} = lists:foldl(fun(Handshake, {Acc,Cs0}) -> + Frags = dtls_handshake:fragment_handshake(Handshake, MaxFragmentSize), + lists:foldl(Encode, {Acc,Cs0}, Frags) + end, {[], ConnectionStates}, Flight), + {lists:reverse(Rev), Cs}. encode_change_cipher(#change_cipher_spec{}, Version, Epoch, ConnectionStates) -> dtls_record:encode_change_cipher_spec(Version, Epoch, ConnectionStates). diff --git a/lib/ssl/src/dtls_record.erl b/lib/ssl/src/dtls_record.erl index da8d19d6ed..f0d2a91a67 100644 --- a/lib/ssl/src/dtls_record.erl +++ b/lib/ssl/src/dtls_record.erl @@ -204,16 +204,17 @@ encode_alert_record(#alert{level = Level, description = Description}, %%-------------------------------------------------------------------- -spec encode_change_cipher_spec(ssl_record:ssl_version(), integer(), ssl_record:connection_states()) -> - {iolist(), ssl_record:connection_states()}. + {[iolist()], ssl_record:connection_states()}. %% %% Description: Encodes a change_cipher_spec-message to send on the ssl socket. %%-------------------------------------------------------------------- encode_change_cipher_spec(Version, Epoch, ConnectionStates) -> - encode_plain_text(?CHANGE_CIPHER_SPEC, Version, Epoch, ?byte(?CHANGE_CIPHER_SPEC_PROTO), ConnectionStates). + {Enc, Cs} = encode_plain_text(?CHANGE_CIPHER_SPEC, Version, Epoch, ?byte(?CHANGE_CIPHER_SPEC_PROTO), ConnectionStates), + {[Enc], Cs}. %%-------------------------------------------------------------------- -spec encode_data(binary(), ssl_record:ssl_version(), ssl_record:connection_states()) -> - {iolist(),ssl_record:connection_states()}. + {[iolist()],ssl_record:connection_states()}. %% %% Description: Encodes data to send on the ssl-socket. %%-------------------------------------------------------------------- @@ -236,7 +237,8 @@ encode_data(Data, Version, ConnectionStates) -> end, {[], ConnectionStates}, Frags), {lists:reverse(RevCipherText), ConnectionStates1}; _ -> - encode_plain_text(?APPLICATION_DATA, Version, Epoch, Data, ConnectionStates) + {Enc, Cs} = encode_plain_text(?APPLICATION_DATA, Version, Epoch, Data, ConnectionStates), + {[Enc], Cs} end. encode_plain_text(Type, Version, Epoch, Data, ConnectionStates) -> -- 2.31.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor