aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src/dtls_handshake.erl
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2017-03-23 14:53:43 +0100
committerIngela Anderton Andin <[email protected]>2017-03-23 14:53:43 +0100
commitdae0ee2186affe46d881f7662f73361b26f38b68 (patch)
treedb4a955e1ce681fbddcdfc6b6e0969f2422d37fb /lib/ssl/src/dtls_handshake.erl
parentf7d248a6794655809e2fdc7d0d1932bbb3dc8cc0 (diff)
parenta28b1903efbfdb41d3d8437b4fe54691ced376a8 (diff)
downloadotp-dae0ee2186affe46d881f7662f73361b26f38b68.tar.gz
otp-dae0ee2186affe46d881f7662f73361b26f38b68.tar.bz2
otp-dae0ee2186affe46d881f7662f73361b26f38b68.zip
Merge branch 'ingela/ssl/dtls-frag'
* ingela/ssl/dtls-frag: dtls: Handle overlapping fragments
Diffstat (limited to 'lib/ssl/src/dtls_handshake.erl')
-rw-r--r--lib/ssl/src/dtls_handshake.erl28
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/ssl/src/dtls_handshake.erl b/lib/ssl/src/dtls_handshake.erl
index fd1f9698fe..4c525fae1b 100644
--- a/lib/ssl/src/dtls_handshake.erl
+++ b/lib/ssl/src/dtls_handshake.erl
@@ -455,7 +455,7 @@ merge_fragments(#handshake_fragment{
fragment_offset = PreviousOffSet,
fragment_length = CurrentLen}) when CurrentLen < PreviousLen ->
Previous;
-%% Next fragment
+%% Next fragment, might be overlapping
merge_fragments(#handshake_fragment{
fragment_offset = PreviousOffSet,
fragment_length = PreviousLen,
@@ -464,10 +464,28 @@ merge_fragments(#handshake_fragment{
#handshake_fragment{
fragment_offset = CurrentOffSet,
fragment_length = CurrentLen,
- fragment = CurrentData}) when PreviousOffSet + PreviousLen == CurrentOffSet->
- Previous#handshake_fragment{
- fragment_length = PreviousLen + CurrentLen,
- fragment = <<PreviousData/binary, CurrentData/binary>>};
+ fragment = CurrentData})
+ when PreviousOffSet + PreviousLen >= CurrentOffSet andalso
+ PreviousOffSet + PreviousLen < CurrentOffSet + CurrentLen ->
+ CurrentStart = PreviousOffSet + PreviousLen - CurrentOffSet,
+ <<_:CurrentStart/bytes, Data/binary>> = CurrentData,
+ Previous#handshake_fragment{
+ fragment_length = PreviousLen + CurrentLen - CurrentStart,
+ fragment = <<PreviousData/binary, Data/binary>>};
+%% already fully contained fragment
+merge_fragments(#handshake_fragment{
+ fragment_offset = PreviousOffSet,
+ fragment_length = PreviousLen,
+ fragment = PreviousData
+ } = Previous,
+ #handshake_fragment{
+ fragment_offset = CurrentOffSet,
+ fragment_length = CurrentLen,
+ fragment = CurrentData})
+ when PreviousOffSet + PreviousLen >= CurrentOffSet andalso
+ PreviousOffSet + PreviousLen >= CurrentOffSet + CurrentLen ->
+ Previous;
+
%% No merge there is a gap
merge_fragments(Previous, Current) ->
[Previous, Current].