|
@@ -88,8 +88,8 @@ public class Kcp
|
|
|
public static T[] slice<T>(T[] p, int start, int stop)
|
|
public static T[] slice<T>(T[] p, int start, int stop)
|
|
|
{
|
|
{
|
|
|
var arr = new T[stop - start];
|
|
var arr = new T[stop - start];
|
|
|
- var index = 0;
|
|
|
|
|
- for (var i = start; i < stop; i++)
|
|
|
|
|
|
|
+ int index = 0;
|
|
|
|
|
+ for (int i = start; i < stop; i++)
|
|
|
{
|
|
{
|
|
|
arr[index] = p[i];
|
|
arr[index] = p[i];
|
|
|
index++;
|
|
index++;
|
|
@@ -109,7 +109,7 @@ public class Kcp
|
|
|
public static T[] append<T>(T[] p, T c)
|
|
public static T[] append<T>(T[] p, T c)
|
|
|
{
|
|
{
|
|
|
var arr = new T[p.Length + 1];
|
|
var arr = new T[p.Length + 1];
|
|
|
- for (var i = 0; i < p.Length; i++)
|
|
|
|
|
|
|
+ for (int i = 0; i < p.Length; i++)
|
|
|
arr[i] = p[i];
|
|
arr[i] = p[i];
|
|
|
arr[p.Length] = c;
|
|
arr[p.Length] = c;
|
|
|
return arr;
|
|
return arr;
|
|
@@ -118,9 +118,9 @@ public class Kcp
|
|
|
public static T[] append<T>(T[] p, T[] cs)
|
|
public static T[] append<T>(T[] p, T[] cs)
|
|
|
{
|
|
{
|
|
|
var arr = new T[p.Length + cs.Length];
|
|
var arr = new T[p.Length + cs.Length];
|
|
|
- for (var i = 0; i < p.Length; i++)
|
|
|
|
|
|
|
+ for (int i = 0; i < p.Length; i++)
|
|
|
arr[i] = p[i];
|
|
arr[i] = p[i];
|
|
|
- for (var i = 0; i < cs.Length; i++)
|
|
|
|
|
|
|
+ for (int i = 0; i < cs.Length; i++)
|
|
|
arr[p.Length + i] = cs[i];
|
|
arr[p.Length + i] = cs[i];
|
|
|
return arr;
|
|
return arr;
|
|
|
}
|
|
}
|
|
@@ -169,7 +169,7 @@ public class Kcp
|
|
|
// encode a segment into buffer
|
|
// encode a segment into buffer
|
|
|
internal int encode(byte[] ptr, int offset)
|
|
internal int encode(byte[] ptr, int offset)
|
|
|
{
|
|
{
|
|
|
- var offset_ = offset;
|
|
|
|
|
|
|
+ int offset_ = offset;
|
|
|
|
|
|
|
|
offset += ikcp_encode32u(ptr, offset, conv);
|
|
offset += ikcp_encode32u(ptr, offset, conv);
|
|
|
offset += ikcp_encode8u(ptr, offset, (byte)cmd);
|
|
offset += ikcp_encode8u(ptr, offset, (byte)cmd);
|
|
@@ -259,7 +259,7 @@ public class Kcp
|
|
|
if (0 == rcv_queue.Length)
|
|
if (0 == rcv_queue.Length)
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
|
|
- var seq = rcv_queue[0];
|
|
|
|
|
|
|
+ Segment seq = rcv_queue[0];
|
|
|
|
|
|
|
|
if (0 == seq.frg)
|
|
if (0 == seq.frg)
|
|
|
return seq.data.Length;
|
|
return seq.data.Length;
|
|
@@ -269,7 +269,7 @@ public class Kcp
|
|
|
|
|
|
|
|
int length = 0;
|
|
int length = 0;
|
|
|
|
|
|
|
|
- foreach (var item in rcv_queue)
|
|
|
|
|
|
|
+ foreach (Segment item in rcv_queue)
|
|
|
{
|
|
{
|
|
|
length += item.data.Length;
|
|
length += item.data.Length;
|
|
|
if (0 == item.frg)
|
|
if (0 == item.frg)
|
|
@@ -285,21 +285,21 @@ public class Kcp
|
|
|
if (0 == rcv_queue.Length)
|
|
if (0 == rcv_queue.Length)
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
|
|
- var peekSize = PeekSize();
|
|
|
|
|
|
|
+ int peekSize = PeekSize();
|
|
|
if (0 > peekSize)
|
|
if (0 > peekSize)
|
|
|
return -2;
|
|
return -2;
|
|
|
|
|
|
|
|
if (peekSize > buffer.Length)
|
|
if (peekSize > buffer.Length)
|
|
|
return -3;
|
|
return -3;
|
|
|
|
|
|
|
|
- var fast_recover = false;
|
|
|
|
|
|
|
+ bool fast_recover = false;
|
|
|
if (rcv_queue.Length >= rcv_wnd)
|
|
if (rcv_queue.Length >= rcv_wnd)
|
|
|
fast_recover = true;
|
|
fast_recover = true;
|
|
|
|
|
|
|
|
// merge fragment.
|
|
// merge fragment.
|
|
|
- var count = 0;
|
|
|
|
|
- var n = 0;
|
|
|
|
|
- foreach (var seg in rcv_queue)
|
|
|
|
|
|
|
+ int count = 0;
|
|
|
|
|
+ int n = 0;
|
|
|
|
|
+ foreach (Segment seg in rcv_queue)
|
|
|
{
|
|
{
|
|
|
Array.Copy(seg.data, 0, buffer, n, seg.data.Length);
|
|
Array.Copy(seg.data, 0, buffer, n, seg.data.Length);
|
|
|
n += seg.data.Length;
|
|
n += seg.data.Length;
|
|
@@ -313,7 +313,7 @@ public class Kcp
|
|
|
|
|
|
|
|
// move available data from rcv_buf -> rcv_queue
|
|
// move available data from rcv_buf -> rcv_queue
|
|
|
count = 0;
|
|
count = 0;
|
|
|
- foreach (var seg in rcv_buf)
|
|
|
|
|
|
|
+ foreach (Segment seg in rcv_buf)
|
|
|
if (seg.sn == this.rcv_nxt && this.rcv_queue.Length < this.rcv_wnd)
|
|
if (seg.sn == this.rcv_nxt && this.rcv_queue.Length < this.rcv_wnd)
|
|
|
{
|
|
{
|
|
|
this.rcv_queue = append(this.rcv_queue, seg);
|
|
this.rcv_queue = append(this.rcv_queue, seg);
|
|
@@ -346,7 +346,7 @@ public class Kcp
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- var count = 0;
|
|
|
|
|
|
|
+ int count = 0;
|
|
|
|
|
|
|
|
if (length < mss)
|
|
if (length < mss)
|
|
|
count = 1;
|
|
count = 1;
|
|
@@ -359,17 +359,17 @@ public class Kcp
|
|
|
if (0 == count)
|
|
if (0 == count)
|
|
|
count = 1;
|
|
count = 1;
|
|
|
|
|
|
|
|
- var offset = 0;
|
|
|
|
|
|
|
+ int offset = 0;
|
|
|
|
|
|
|
|
- for (var i = 0; i < count; i++)
|
|
|
|
|
|
|
+ for (int i = 0; i < count; i++)
|
|
|
{
|
|
{
|
|
|
- var size = 0;
|
|
|
|
|
|
|
+ int size = 0;
|
|
|
if (length - offset > mss)
|
|
if (length - offset > mss)
|
|
|
size = (int)mss;
|
|
size = (int)mss;
|
|
|
else
|
|
else
|
|
|
size = length - offset;
|
|
size = length - offset;
|
|
|
|
|
|
|
|
- var seg = new Segment(size);
|
|
|
|
|
|
|
+ Segment seg = new Segment(size);
|
|
|
Array.Copy(bytes, offset + index, seg.data, 0, size);
|
|
Array.Copy(bytes, offset + index, seg.data, 0, size);
|
|
|
offset += size;
|
|
offset += size;
|
|
|
seg.frg = (UInt32)(count - i - 1);
|
|
seg.frg = (UInt32)(count - i - 1);
|
|
@@ -399,7 +399,7 @@ public class Kcp
|
|
|
rx_srtt = 1;
|
|
rx_srtt = 1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- var rto = (int)(rx_srtt + _imax_(1, 4 * rx_rttval));
|
|
|
|
|
|
|
+ int rto = (int)(rx_srtt + _imax_(1, 4 * rx_rttval));
|
|
|
rx_rto = _ibound_(rx_minrto, (UInt32)rto, IKCP_RTO_MAX);
|
|
rx_rto = _ibound_(rx_minrto, (UInt32)rto, IKCP_RTO_MAX);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -416,8 +416,8 @@ public class Kcp
|
|
|
if (_itimediff(sn, snd_una) < 0 || _itimediff(sn, snd_nxt) >= 0)
|
|
if (_itimediff(sn, snd_una) < 0 || _itimediff(sn, snd_nxt) >= 0)
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
- var index = 0;
|
|
|
|
|
- foreach (var seg in snd_buf)
|
|
|
|
|
|
|
+ int index = 0;
|
|
|
|
|
+ foreach (Segment seg in snd_buf)
|
|
|
{
|
|
{
|
|
|
if (sn == seg.sn)
|
|
if (sn == seg.sn)
|
|
|
{
|
|
{
|
|
@@ -432,8 +432,8 @@ public class Kcp
|
|
|
|
|
|
|
|
private void parse_una(UInt32 una)
|
|
private void parse_una(UInt32 una)
|
|
|
{
|
|
{
|
|
|
- var count = 0;
|
|
|
|
|
- foreach (var seg in snd_buf)
|
|
|
|
|
|
|
+ int count = 0;
|
|
|
|
|
+ foreach (Segment seg in snd_buf)
|
|
|
if (_itimediff(una, seg.sn) > 0)
|
|
if (_itimediff(una, seg.sn) > 0)
|
|
|
count++;
|
|
count++;
|
|
|
else
|
|
else
|
|
@@ -456,16 +456,16 @@ public class Kcp
|
|
|
|
|
|
|
|
private void parse_data(Segment newseg)
|
|
private void parse_data(Segment newseg)
|
|
|
{
|
|
{
|
|
|
- var sn = newseg.sn;
|
|
|
|
|
|
|
+ uint sn = newseg.sn;
|
|
|
if (_itimediff(sn, rcv_nxt + rcv_wnd) >= 0 || _itimediff(sn, rcv_nxt) < 0)
|
|
if (_itimediff(sn, rcv_nxt + rcv_wnd) >= 0 || _itimediff(sn, rcv_nxt) < 0)
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
- var n = rcv_buf.Length - 1;
|
|
|
|
|
- var after_idx = -1;
|
|
|
|
|
- var repeat = false;
|
|
|
|
|
- for (var i = n; i >= 0; i--)
|
|
|
|
|
|
|
+ int n = rcv_buf.Length - 1;
|
|
|
|
|
+ int after_idx = -1;
|
|
|
|
|
+ bool repeat = false;
|
|
|
|
|
+ for (int i = n; i >= 0; i--)
|
|
|
{
|
|
{
|
|
|
- var seg = rcv_buf[i];
|
|
|
|
|
|
|
+ Segment seg = rcv_buf[i];
|
|
|
if (seg.sn == sn)
|
|
if (seg.sn == sn)
|
|
|
{
|
|
{
|
|
|
repeat = true;
|
|
repeat = true;
|
|
@@ -487,8 +487,8 @@ public class Kcp
|
|
|
append(new Segment[1] { newseg }, slice(this.rcv_buf, after_idx + 1, this.rcv_buf.Length)));
|
|
append(new Segment[1] { newseg }, slice(this.rcv_buf, after_idx + 1, this.rcv_buf.Length)));
|
|
|
|
|
|
|
|
// move available data from rcv_buf -> rcv_queue
|
|
// move available data from rcv_buf -> rcv_queue
|
|
|
- var count = 0;
|
|
|
|
|
- foreach (var seg in rcv_buf)
|
|
|
|
|
|
|
+ int count = 0;
|
|
|
|
|
+ foreach (Segment seg in rcv_buf)
|
|
|
if (seg.sn == this.rcv_nxt && this.rcv_queue.Length < this.rcv_wnd)
|
|
if (seg.sn == this.rcv_nxt && this.rcv_queue.Length < this.rcv_wnd)
|
|
|
{
|
|
{
|
|
|
this.rcv_queue = append(this.rcv_queue, seg);
|
|
this.rcv_queue = append(this.rcv_queue, seg);
|
|
@@ -507,11 +507,11 @@ public class Kcp
|
|
|
// when you received a low level packet (eg. UDP packet), call it
|
|
// when you received a low level packet (eg. UDP packet), call it
|
|
|
public int Input(byte[] data)
|
|
public int Input(byte[] data)
|
|
|
{
|
|
{
|
|
|
- var s_una = snd_una;
|
|
|
|
|
|
|
+ uint s_una = snd_una;
|
|
|
if (data.Length < IKCP_OVERHEAD)
|
|
if (data.Length < IKCP_OVERHEAD)
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
- var offset = 0;
|
|
|
|
|
|
|
+ int offset = 0;
|
|
|
|
|
|
|
|
while (true)
|
|
while (true)
|
|
|
{
|
|
{
|
|
@@ -575,7 +575,7 @@ public class Kcp
|
|
|
ack_push(sn, ts);
|
|
ack_push(sn, ts);
|
|
|
if (_itimediff(sn, rcv_nxt) >= 0)
|
|
if (_itimediff(sn, rcv_nxt) >= 0)
|
|
|
{
|
|
{
|
|
|
- var seg = new Segment((int)length);
|
|
|
|
|
|
|
+ Segment seg = new Segment((int)length);
|
|
|
seg.conv = conv_;
|
|
seg.conv = conv_;
|
|
|
seg.cmd = cmd;
|
|
seg.cmd = cmd;
|
|
|
seg.frg = frg;
|
|
seg.frg = frg;
|
|
@@ -612,7 +612,7 @@ public class Kcp
|
|
|
if (_itimediff(snd_una, s_una) > 0)
|
|
if (_itimediff(snd_una, s_una) > 0)
|
|
|
if (this.cwnd < this.rmt_wnd)
|
|
if (this.cwnd < this.rmt_wnd)
|
|
|
{
|
|
{
|
|
|
- var mss_ = this.mss;
|
|
|
|
|
|
|
+ uint mss_ = this.mss;
|
|
|
if (this.cwnd < this.ssthresh)
|
|
if (this.cwnd < this.ssthresh)
|
|
|
{
|
|
{
|
|
|
this.cwnd++;
|
|
this.cwnd++;
|
|
@@ -646,24 +646,24 @@ public class Kcp
|
|
|
// flush pending data
|
|
// flush pending data
|
|
|
private void flush()
|
|
private void flush()
|
|
|
{
|
|
{
|
|
|
- var current_ = current;
|
|
|
|
|
|
|
+ uint current_ = current;
|
|
|
var buffer_ = buffer;
|
|
var buffer_ = buffer;
|
|
|
- var change = 0;
|
|
|
|
|
- var lost = 0;
|
|
|
|
|
|
|
+ int change = 0;
|
|
|
|
|
+ int lost = 0;
|
|
|
|
|
|
|
|
if (0 == updated)
|
|
if (0 == updated)
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
- var seg = new Segment(0);
|
|
|
|
|
|
|
+ Segment seg = new Segment(0);
|
|
|
seg.conv = conv;
|
|
seg.conv = conv;
|
|
|
seg.cmd = IKCP_CMD_ACK;
|
|
seg.cmd = IKCP_CMD_ACK;
|
|
|
seg.wnd = (UInt32)wnd_unused();
|
|
seg.wnd = (UInt32)wnd_unused();
|
|
|
seg.una = rcv_nxt;
|
|
seg.una = rcv_nxt;
|
|
|
|
|
|
|
|
// flush acknowledges
|
|
// flush acknowledges
|
|
|
- var count = acklist.Length / 2;
|
|
|
|
|
- var offset = 0;
|
|
|
|
|
- for (var i = 0; i < count; i++)
|
|
|
|
|
|
|
+ int count = acklist.Length / 2;
|
|
|
|
|
+ int offset = 0;
|
|
|
|
|
+ for (int i = 0; i < count; i++)
|
|
|
{
|
|
{
|
|
|
if (offset + IKCP_OVERHEAD > mtu)
|
|
if (offset + IKCP_OVERHEAD > mtu)
|
|
|
{
|
|
{
|
|
@@ -720,17 +720,17 @@ public class Kcp
|
|
|
probe = 0;
|
|
probe = 0;
|
|
|
|
|
|
|
|
// calculate window size
|
|
// calculate window size
|
|
|
- var cwnd_ = _imin_(snd_wnd, rmt_wnd);
|
|
|
|
|
|
|
+ uint cwnd_ = _imin_(snd_wnd, rmt_wnd);
|
|
|
if (0 == nocwnd)
|
|
if (0 == nocwnd)
|
|
|
cwnd_ = _imin_(cwnd, cwnd_);
|
|
cwnd_ = _imin_(cwnd, cwnd_);
|
|
|
|
|
|
|
|
count = 0;
|
|
count = 0;
|
|
|
- for (var k = 0; k < snd_queue.Length; k++)
|
|
|
|
|
|
|
+ for (int k = 0; k < snd_queue.Length; k++)
|
|
|
{
|
|
{
|
|
|
if (_itimediff(snd_nxt, snd_una + cwnd_) >= 0)
|
|
if (_itimediff(snd_nxt, snd_una + cwnd_) >= 0)
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
- var newseg = snd_queue[k];
|
|
|
|
|
|
|
+ Segment newseg = snd_queue[k];
|
|
|
newseg.conv = conv;
|
|
newseg.conv = conv;
|
|
|
newseg.cmd = IKCP_CMD_PUSH;
|
|
newseg.cmd = IKCP_CMD_PUSH;
|
|
|
newseg.wnd = seg.wnd;
|
|
newseg.wnd = seg.wnd;
|
|
@@ -750,18 +750,18 @@ public class Kcp
|
|
|
this.snd_queue = slice(this.snd_queue, count, this.snd_queue.Length);
|
|
this.snd_queue = slice(this.snd_queue, count, this.snd_queue.Length);
|
|
|
|
|
|
|
|
// calculate resent
|
|
// calculate resent
|
|
|
- var resent = (UInt32)fastresend;
|
|
|
|
|
|
|
+ uint resent = (UInt32)fastresend;
|
|
|
if (fastresend <= 0)
|
|
if (fastresend <= 0)
|
|
|
resent = 0xffffffff;
|
|
resent = 0xffffffff;
|
|
|
- var rtomin = rx_rto >> 3;
|
|
|
|
|
|
|
+ uint rtomin = rx_rto >> 3;
|
|
|
if (nodelay != 0)
|
|
if (nodelay != 0)
|
|
|
rtomin = 0;
|
|
rtomin = 0;
|
|
|
|
|
|
|
|
// flush data segments
|
|
// flush data segments
|
|
|
- foreach (var segment in snd_buf)
|
|
|
|
|
|
|
+ foreach (Segment segment in snd_buf)
|
|
|
{
|
|
{
|
|
|
- var needsend = false;
|
|
|
|
|
- var debug = _itimediff(current_, segment.resendts);
|
|
|
|
|
|
|
+ bool needsend = false;
|
|
|
|
|
+ int debug = _itimediff(current_, segment.resendts);
|
|
|
if (0 == segment.xmit)
|
|
if (0 == segment.xmit)
|
|
|
{
|
|
{
|
|
|
needsend = true;
|
|
needsend = true;
|
|
@@ -796,7 +796,7 @@ public class Kcp
|
|
|
segment.wnd = seg.wnd;
|
|
segment.wnd = seg.wnd;
|
|
|
segment.una = rcv_nxt;
|
|
segment.una = rcv_nxt;
|
|
|
|
|
|
|
|
- var need = IKCP_OVERHEAD + segment.data.Length;
|
|
|
|
|
|
|
+ int need = IKCP_OVERHEAD + segment.data.Length;
|
|
|
if (offset + need > mtu)
|
|
if (offset + need > mtu)
|
|
|
{
|
|
{
|
|
|
output(buffer, offset);
|
|
output(buffer, offset);
|
|
@@ -827,7 +827,7 @@ public class Kcp
|
|
|
// update ssthresh
|
|
// update ssthresh
|
|
|
if (change != 0)
|
|
if (change != 0)
|
|
|
{
|
|
{
|
|
|
- var inflight = snd_nxt - snd_una;
|
|
|
|
|
|
|
+ uint inflight = snd_nxt - snd_una;
|
|
|
ssthresh = inflight / 2;
|
|
ssthresh = inflight / 2;
|
|
|
if (ssthresh < IKCP_THRESH_MIN)
|
|
if (ssthresh < IKCP_THRESH_MIN)
|
|
|
ssthresh = IKCP_THRESH_MIN;
|
|
ssthresh = IKCP_THRESH_MIN;
|
|
@@ -864,7 +864,7 @@ public class Kcp
|
|
|
ts_flush = current;
|
|
ts_flush = current;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- var slap = _itimediff(current, ts_flush);
|
|
|
|
|
|
|
+ int slap = _itimediff(current, ts_flush);
|
|
|
|
|
|
|
|
if (slap >= 10000 || slap < -10000)
|
|
if (slap >= 10000 || slap < -10000)
|
|
|
{
|
|
{
|
|
@@ -893,10 +893,10 @@ public class Kcp
|
|
|
if (0 == updated)
|
|
if (0 == updated)
|
|
|
return current_;
|
|
return current_;
|
|
|
|
|
|
|
|
- var ts_flush_ = ts_flush;
|
|
|
|
|
- var tm_flush_ = 0x7fffffff;
|
|
|
|
|
- var tm_packet = 0x7fffffff;
|
|
|
|
|
- var minimal = 0;
|
|
|
|
|
|
|
+ uint ts_flush_ = ts_flush;
|
|
|
|
|
+ int tm_flush_ = 0x7fffffff;
|
|
|
|
|
+ int tm_packet = 0x7fffffff;
|
|
|
|
|
+ int minimal = 0;
|
|
|
|
|
|
|
|
if (_itimediff(current_, ts_flush_) >= 10000 || _itimediff(current_, ts_flush_) < -10000)
|
|
if (_itimediff(current_, ts_flush_) >= 10000 || _itimediff(current_, ts_flush_) < -10000)
|
|
|
ts_flush_ = current_;
|
|
ts_flush_ = current_;
|
|
@@ -906,9 +906,9 @@ public class Kcp
|
|
|
|
|
|
|
|
tm_flush_ = _itimediff(ts_flush_, current_);
|
|
tm_flush_ = _itimediff(ts_flush_, current_);
|
|
|
|
|
|
|
|
- foreach (var seg in snd_buf)
|
|
|
|
|
|
|
+ foreach (Segment seg in snd_buf)
|
|
|
{
|
|
{
|
|
|
- var diff = _itimediff(seg.resendts, current_);
|
|
|
|
|
|
|
+ int diff = _itimediff(seg.resendts, current_);
|
|
|
if (diff <= 0)
|
|
if (diff <= 0)
|
|
|
return current_;
|
|
return current_;
|
|
|
if (diff < tm_packet)
|
|
if (diff < tm_packet)
|