DtlsReassembler.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  6. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Tls
  7. {
  8. class DtlsReassembler
  9. {
  10. private readonly byte mMsgType;
  11. private readonly byte[] mBody;
  12. private readonly IList mMissing = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
  13. internal DtlsReassembler(byte msg_type, int length)
  14. {
  15. this.mMsgType = msg_type;
  16. this.mBody = new byte[length];
  17. this.mMissing.Add(new Range(0, length));
  18. }
  19. internal byte MsgType
  20. {
  21. get { return mMsgType; }
  22. }
  23. internal byte[] GetBodyIfComplete()
  24. {
  25. return mMissing.Count == 0 ? mBody : null;
  26. }
  27. internal void ContributeFragment(byte msg_type, int length, byte[] buf, int off, int fragment_offset,
  28. int fragment_length)
  29. {
  30. int fragment_end = fragment_offset + fragment_length;
  31. if (this.mMsgType != msg_type || this.mBody.Length != length || fragment_end > length)
  32. {
  33. return;
  34. }
  35. if (fragment_length == 0)
  36. {
  37. // NOTE: Empty messages still require an empty fragment to complete it
  38. if (fragment_offset == 0 && mMissing.Count > 0)
  39. {
  40. Range firstRange = (Range)mMissing[0];
  41. if (firstRange.End == 0)
  42. {
  43. mMissing.RemoveAt(0);
  44. }
  45. }
  46. return;
  47. }
  48. for (int i = 0; i < mMissing.Count; ++i)
  49. {
  50. Range range = (Range)mMissing[i];
  51. if (range.Start >= fragment_end)
  52. {
  53. break;
  54. }
  55. if (range.End > fragment_offset)
  56. {
  57. int copyStart = System.Math.Max(range.Start, fragment_offset);
  58. int copyEnd = System.Math.Min(range.End, fragment_end);
  59. int copyLength = copyEnd - copyStart;
  60. Array.Copy(buf, off + copyStart - fragment_offset, mBody, copyStart,
  61. copyLength);
  62. if (copyStart == range.Start)
  63. {
  64. if (copyEnd == range.End)
  65. {
  66. mMissing.RemoveAt(i--);
  67. }
  68. else
  69. {
  70. range.Start = copyEnd;
  71. }
  72. }
  73. else
  74. {
  75. if (copyEnd != range.End)
  76. {
  77. mMissing.Insert(++i, new Range(copyEnd, range.End));
  78. }
  79. range.End = copyStart;
  80. }
  81. }
  82. }
  83. }
  84. internal void Reset()
  85. {
  86. this.mMissing.Clear();
  87. this.mMissing.Add(new Range(0, mBody.Length));
  88. }
  89. private class Range
  90. {
  91. private int mStart, mEnd;
  92. internal Range(int start, int end)
  93. {
  94. this.mStart = start;
  95. this.mEnd = end;
  96. }
  97. public int Start
  98. {
  99. get { return mStart; }
  100. set { this.mStart = value; }
  101. }
  102. public int End
  103. {
  104. get { return mEnd; }
  105. set { this.mEnd = value; }
  106. }
  107. }
  108. }
  109. }
  110. #pragma warning restore
  111. #endif