1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
package org.bouncycastle.crypto.tls;
import java.util.Vector;
class DTLSReassembler
{
private final short msg_type;
private final byte[] body;
private Vector missing = new Vector();
DTLSReassembler(short msg_type, int length)
{
this.msg_type = msg_type;
this.body = new byte[length];
this.missing.addElement(new Range(0, length));
}
short getType()
{
return msg_type;
}
byte[] getBodyIfComplete()
{
return missing.isEmpty() ? body : null;
}
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 (this.msg_type != msg_type || this.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 && !missing.isEmpty())
{
Range firstRange = (Range)missing.firstElement();
if (firstRange.getEnd() == 0)
{
missing.removeElementAt(0);
}
}
return;
}
for (int i = 0; i < missing.size(); ++i)
{
Range range = (Range)missing.get(i);
if (range.getStart() >= fragment_end)
{
break;
}
if (range.getEnd() > fragment_offset)
{
int copyStart = Math.max(range.getStart(), fragment_offset);
int copyEnd = Math.min(range.getEnd(), fragment_end);
int copyLength = copyEnd - copyStart;
System.arraycopy(buf, off + copyStart - fragment_offset, body, copyStart,
copyLength);
if (copyStart == range.getStart())
{
if (copyEnd == range.getEnd())
{
missing.removeElementAt(i--);
}
else
{
range.setStart(copyEnd);
}
}
else
{
if (copyEnd == range.getEnd())
{
range.setEnd(copyStart);
}
else
{
missing.insertElementAt(new Range(copyEnd, range.getEnd()), ++i);
range.setEnd(copyStart);
}
}
}
}
}
void reset()
{
this.missing.clear();
this.missing.addElement(new Range(0, body.length));
}
private static class Range
{
private int start, end;
Range(int start, int end)
{
this.start = start;
this.end = end;
}
public int getStart()
{
return start;
}
public void setStart(int start)
{
this.start = start;
}
public int getEnd()
{
return end;
}
public void setEnd(int end)
{
this.end = end;
}
}
}
|