diff options
author | Ingela Anderton Andin <[email protected]> | 2017-03-15 10:55:45 +0100 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2017-03-23 14:52:25 +0100 |
commit | a28b1903efbfdb41d3d8437b4fe54691ced376a8 (patch) | |
tree | dc1b0c693fd0354aacb72aa5ab6eb755e7a570a4 | |
parent | bce42f4c31bf552269eb787c61a979b3fb34c87e (diff) | |
download | otp-a28b1903efbfdb41d3d8437b4fe54691ced376a8.tar.gz otp-a28b1903efbfdb41d3d8437b4fe54691ced376a8.tar.bz2 otp-a28b1903efbfdb41d3d8437b4fe54691ced376a8.zip |
dtls: Handle overlapping fragments
Fragment reassembling needs to handle that a smaller
fragment then sent originally might overlap an earlier
received fragment.
-rw-r--r-- | lib/ssl/src/dtls_handshake.erl | 28 |
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]. |