130 lines
3.7 KiB
C#
130 lines
3.7 KiB
C#
#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.Crypto.Tls
|
|
{
|
|
class DtlsReassembler
|
|
{
|
|
private readonly byte mMsgType;
|
|
private readonly byte[] mBody;
|
|
|
|
private readonly IList mMissing = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
|
|
|
|
internal DtlsReassembler(byte msg_type, int length)
|
|
{
|
|
this.mMsgType = msg_type;
|
|
this.mBody = new byte[length];
|
|
this.mMissing.Add(new Range(0, length));
|
|
}
|
|
|
|
internal byte MsgType
|
|
{
|
|
get { return mMsgType; }
|
|
}
|
|
|
|
internal byte[] GetBodyIfComplete()
|
|
{
|
|
return mMissing.Count == 0 ? mBody : null;
|
|
}
|
|
|
|
internal void ContributeFragment(byte msg_type, int length, byte[] buf, int off, int fragment_offset,
|
|
int fragment_length)
|
|
{
|
|
int fragment_end = fragment_offset + fragment_length;
|
|
|
|
if (this.mMsgType != msg_type || this.mBody.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 && mMissing.Count > 0)
|
|
{
|
|
Range firstRange = (Range)mMissing[0];
|
|
if (firstRange.End == 0)
|
|
{
|
|
mMissing.RemoveAt(0);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < mMissing.Count; ++i)
|
|
{
|
|
Range range = (Range)mMissing[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, mBody, copyStart,
|
|
copyLength);
|
|
|
|
if (copyStart == range.Start)
|
|
{
|
|
if (copyEnd == range.End)
|
|
{
|
|
mMissing.RemoveAt(i--);
|
|
}
|
|
else
|
|
{
|
|
range.Start = copyEnd;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (copyEnd != range.End)
|
|
{
|
|
mMissing.Insert(++i, new Range(copyEnd, range.End));
|
|
}
|
|
range.End = copyStart;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void Reset()
|
|
{
|
|
this.mMissing.Clear();
|
|
this.mMissing.Add(new Range(0, mBody.Length));
|
|
}
|
|
|
|
private class Range
|
|
{
|
|
private int mStart, mEnd;
|
|
|
|
internal Range(int start, int end)
|
|
{
|
|
this.mStart = start;
|
|
this.mEnd = end;
|
|
}
|
|
|
|
public int Start
|
|
{
|
|
get { return mStart; }
|
|
set { this.mStart = value; }
|
|
}
|
|
|
|
public int End
|
|
{
|
|
get { return mEnd; }
|
|
set { this.mEnd = value; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#pragma warning restore
|
|
#endif
|