You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
3.7 KiB
124 lines
3.7 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
using System.Collections; |
|
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities; |
|
|
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls |
|
{ |
|
internal sealed class DtlsReassembler |
|
{ |
|
private readonly short m_msg_type; |
|
private readonly byte[] m_body; |
|
|
|
private readonly IList m_missing = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList(); |
|
|
|
internal DtlsReassembler(short msg_type, int length) |
|
{ |
|
this.m_msg_type = msg_type; |
|
this.m_body = new byte[length]; |
|
this.m_missing.Add(new Range(0, length)); |
|
} |
|
|
|
internal short MsgType |
|
{ |
|
get { return m_msg_type; } |
|
} |
|
|
|
internal byte[] GetBodyIfComplete() |
|
{ |
|
return m_missing.Count > 0 ? null : m_body; |
|
} |
|
|
|
internal void ContributeFragment(short msg_type, int length, byte[] buf, int off, int fragment_offset, |
|
int fragment_length) |
|
{ |
|
int fragment_end = fragment_offset + fragment_length; |
|
|
|
if (m_msg_type != msg_type || m_body.Length != length || fragment_end > length) |
|
return; |
|
|
|
if (fragment_length == 0) |
|
{ |
|
// NOTE: Empty messages still require an empty fragment to complete it |
|
if (fragment_offset == 0 && m_missing.Count > 0) |
|
{ |
|
Range firstRange = (Range)m_missing[0]; |
|
if (firstRange.End == 0) |
|
{ |
|
m_missing.RemoveAt(0); |
|
} |
|
} |
|
return; |
|
} |
|
|
|
for (int i = 0; i < m_missing.Count; ++i) |
|
{ |
|
Range range = (Range)m_missing[i]; |
|
if (range.Start >= fragment_end) |
|
break; |
|
|
|
if (range.End > fragment_offset) |
|
{ |
|
int copyStart = System.Math.Max(range.Start, fragment_offset); |
|
int copyEnd = System.Math.Min(range.End, fragment_end); |
|
int copyLength = copyEnd - copyStart; |
|
|
|
Array.Copy(buf, off + copyStart - fragment_offset, m_body, copyStart, copyLength); |
|
|
|
if (copyStart == range.Start) |
|
{ |
|
if (copyEnd == range.End) |
|
{ |
|
m_missing.RemoveAt(i--); |
|
} |
|
else |
|
{ |
|
range.Start = copyEnd; |
|
} |
|
} |
|
else |
|
{ |
|
if (copyEnd != range.End) |
|
{ |
|
m_missing.Insert(++i, new Range(copyEnd, range.End)); |
|
} |
|
range.End = copyStart; |
|
} |
|
} |
|
} |
|
} |
|
|
|
internal void Reset() |
|
{ |
|
m_missing.Clear(); |
|
m_missing.Add(new Range(0, m_body.Length)); |
|
} |
|
|
|
private sealed class Range |
|
{ |
|
private int m_start, m_end; |
|
|
|
internal Range(int start, int end) |
|
{ |
|
this.m_start = start; |
|
this.m_end = end; |
|
} |
|
|
|
public int Start |
|
{ |
|
get { return m_start; } |
|
set { this.m_start = value; } |
|
} |
|
|
|
public int End |
|
{ |
|
get { return m_end; } |
|
set { this.m_end = value; } |
|
} |
|
} |
|
} |
|
} |
|
#pragma warning restore |
|
#endif
|
|
|