File 2031-dtls-Handle-overlapping-fragments.patch of Package erlang
From a28b1903efbfdb41d3d8437b4fe54691ced376a8 Mon Sep 17 00:00:00 2001
From: Ingela Anderton Andin <ingela@erlang.org>
Date: Wed, 15 Mar 2017 10:55:45 +0100
Subject: [PATCH] dtls: Handle overlapping fragments
Fragment reassembling needs to handle that a smaller
fragment then sent originally might overlap an earlier
received fragment.
---
lib/ssl/src/dtls_handshake.erl | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/lib/ssl/src/dtls_handshake.erl b/lib/ssl/src/dtls_handshake.erl
index fd1f9698f..4c525fae1 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].
--
2.12.1