mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-01-02 23:47:07 -05:00
kcp cleanup
This commit is contained in:
parent
a6c0ef11ba
commit
630a76d06a
@ -572,7 +572,7 @@ func (c *Connection) Input(segments []Segment) {
|
||||
c.dataInput.Signal()
|
||||
c.dataOutput.Signal()
|
||||
}
|
||||
c.sendingWorker.ProcessReceivingNext(seg.ReceivinNext)
|
||||
c.sendingWorker.ProcessReceivingNext(seg.ReceivingNext)
|
||||
c.receivingWorker.ProcessSendingNext(seg.SendingNext)
|
||||
c.roundTrip.UpdatePeerRTO(seg.PeerRTO, current)
|
||||
seg.Release()
|
||||
@ -628,7 +628,7 @@ func (c *Connection) Ping(current uint32, cmd Command) {
|
||||
seg := NewCmdOnlySegment()
|
||||
seg.Conv = c.meta.Conversation
|
||||
seg.Cmd = cmd
|
||||
seg.ReceivinNext = c.receivingWorker.NextNumber()
|
||||
seg.ReceivingNext = c.receivingWorker.NextNumber()
|
||||
seg.SendingNext = c.sendingWorker.FirstUnacknowledged()
|
||||
seg.PeerRTO = c.roundTrip.Timeout()
|
||||
if c.State() == StateReadyToClose {
|
||||
|
@ -74,25 +74,25 @@ func NewListener(ctx context.Context, address net.Address, port net.Port, addCon
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func (v *Listener) OnReceive(payload *buf.Buffer, src net.Destination, originalDest net.Destination) {
|
||||
func (l *Listener) OnReceive(payload *buf.Buffer, src net.Destination, originalDest net.Destination) {
|
||||
defer payload.Release()
|
||||
|
||||
segments := v.reader.Read(payload.Bytes())
|
||||
segments := l.reader.Read(payload.Bytes())
|
||||
if len(segments) == 0 {
|
||||
newError("discarding invalid payload from ", src).WriteToLog()
|
||||
return
|
||||
}
|
||||
|
||||
v.Lock()
|
||||
defer v.Unlock()
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
|
||||
select {
|
||||
case <-v.ctx.Done():
|
||||
case <-l.ctx.Done():
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
if v.hub == nil {
|
||||
if l.hub == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ func (v *Listener) OnReceive(payload *buf.Buffer, src net.Destination, originalD
|
||||
Port: src.Port,
|
||||
Conv: conv,
|
||||
}
|
||||
conn, found := v.sessions[id]
|
||||
conn, found := l.sessions[id]
|
||||
|
||||
if !found {
|
||||
if cmd == CommandTerminate {
|
||||
@ -112,73 +112,73 @@ func (v *Listener) OnReceive(payload *buf.Buffer, src net.Destination, originalD
|
||||
}
|
||||
writer := &Writer{
|
||||
id: id,
|
||||
hub: v.hub,
|
||||
hub: l.hub,
|
||||
dest: src,
|
||||
listener: v,
|
||||
listener: l,
|
||||
}
|
||||
remoteAddr := &net.UDPAddr{
|
||||
IP: src.Address.IP(),
|
||||
Port: int(src.Port),
|
||||
}
|
||||
localAddr := v.hub.Addr()
|
||||
localAddr := l.hub.Addr()
|
||||
conn = NewConnection(ConnMetadata{
|
||||
LocalAddr: localAddr,
|
||||
RemoteAddr: remoteAddr,
|
||||
Conversation: conv,
|
||||
}, &KCPPacketWriter{
|
||||
Header: v.header,
|
||||
Security: v.security,
|
||||
Header: l.header,
|
||||
Security: l.security,
|
||||
Writer: writer,
|
||||
}, writer, v.config)
|
||||
}, writer, l.config)
|
||||
var netConn internet.Connection = conn
|
||||
if v.tlsConfig != nil {
|
||||
tlsConn := tls.Server(conn, v.tlsConfig)
|
||||
if l.tlsConfig != nil {
|
||||
tlsConn := tls.Server(conn, l.tlsConfig)
|
||||
netConn = tlsConn
|
||||
}
|
||||
|
||||
if !v.addConn(context.Background(), netConn) {
|
||||
if !l.addConn(context.Background(), netConn) {
|
||||
return
|
||||
}
|
||||
v.sessions[id] = conn
|
||||
l.sessions[id] = conn
|
||||
}
|
||||
conn.Input(segments)
|
||||
}
|
||||
|
||||
func (v *Listener) Remove(id ConnectionID) {
|
||||
func (l *Listener) Remove(id ConnectionID) {
|
||||
select {
|
||||
case <-v.ctx.Done():
|
||||
case <-l.ctx.Done():
|
||||
return
|
||||
default:
|
||||
v.Lock()
|
||||
delete(v.sessions, id)
|
||||
v.Unlock()
|
||||
l.Lock()
|
||||
delete(l.sessions, id)
|
||||
l.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// Close stops listening on the UDP address. Already Accepted connections are not closed.
|
||||
func (v *Listener) Close() error {
|
||||
v.hub.Close()
|
||||
func (l *Listener) Close() error {
|
||||
l.hub.Close()
|
||||
|
||||
v.Lock()
|
||||
defer v.Unlock()
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
|
||||
for _, conn := range v.sessions {
|
||||
for _, conn := range l.sessions {
|
||||
go conn.Terminate()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Listener) ActiveConnections() int {
|
||||
v.Lock()
|
||||
defer v.Unlock()
|
||||
func (l *Listener) ActiveConnections() int {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
|
||||
return len(v.sessions)
|
||||
return len(l.sessions)
|
||||
}
|
||||
|
||||
// Addr returns the listener's network address, The Addr returned is shared by all invocations of Addr, so do not modify it.
|
||||
func (v *Listener) Addr() net.Addr {
|
||||
return v.hub.Addr()
|
||||
func (l *Listener) Addr() net.Addr {
|
||||
return l.hub.Addr()
|
||||
}
|
||||
|
||||
type Writer struct {
|
||||
@ -188,12 +188,12 @@ type Writer struct {
|
||||
listener *Listener
|
||||
}
|
||||
|
||||
func (v *Writer) Write(payload []byte) (int, error) {
|
||||
return v.hub.WriteTo(payload, v.dest)
|
||||
func (w *Writer) Write(payload []byte) (int, error) {
|
||||
return w.hub.WriteTo(payload, w.dest)
|
||||
}
|
||||
|
||||
func (v *Writer) Close() error {
|
||||
v.listener.Remove(v.id)
|
||||
func (w *Writer) Close() error {
|
||||
w.listener.Remove(w.id)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -20,42 +20,42 @@ func NewReceivingWindow(size uint32) *ReceivingWindow {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *ReceivingWindow) Size() uint32 {
|
||||
return v.size
|
||||
func (w *ReceivingWindow) Size() uint32 {
|
||||
return w.size
|
||||
}
|
||||
|
||||
func (v *ReceivingWindow) Position(idx uint32) uint32 {
|
||||
return (idx + v.start) % v.size
|
||||
func (w *ReceivingWindow) Position(idx uint32) uint32 {
|
||||
return (idx + w.start) % w.size
|
||||
}
|
||||
|
||||
func (v *ReceivingWindow) Set(idx uint32, value *DataSegment) bool {
|
||||
pos := v.Position(idx)
|
||||
if v.list[pos] != nil {
|
||||
func (w *ReceivingWindow) Set(idx uint32, value *DataSegment) bool {
|
||||
pos := w.Position(idx)
|
||||
if w.list[pos] != nil {
|
||||
return false
|
||||
}
|
||||
v.list[pos] = value
|
||||
w.list[pos] = value
|
||||
return true
|
||||
}
|
||||
|
||||
func (v *ReceivingWindow) Remove(idx uint32) *DataSegment {
|
||||
pos := v.Position(idx)
|
||||
e := v.list[pos]
|
||||
v.list[pos] = nil
|
||||
func (w *ReceivingWindow) Remove(idx uint32) *DataSegment {
|
||||
pos := w.Position(idx)
|
||||
e := w.list[pos]
|
||||
w.list[pos] = nil
|
||||
return e
|
||||
}
|
||||
|
||||
func (v *ReceivingWindow) RemoveFirst() *DataSegment {
|
||||
return v.Remove(0)
|
||||
func (w *ReceivingWindow) RemoveFirst() *DataSegment {
|
||||
return w.Remove(0)
|
||||
}
|
||||
|
||||
func (w *ReceivingWindow) HasFirst() bool {
|
||||
return w.list[w.Position(0)] != nil
|
||||
}
|
||||
|
||||
func (v *ReceivingWindow) Advance() {
|
||||
v.start++
|
||||
if v.start == v.size {
|
||||
v.start = 0
|
||||
func (w *ReceivingWindow) Advance() {
|
||||
w.start++
|
||||
if w.start == w.size {
|
||||
w.start = 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,70 +79,70 @@ func NewAckList(writer SegmentWriter) *AckList {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *AckList) Add(number uint32, timestamp uint32) {
|
||||
v.timestamps = append(v.timestamps, timestamp)
|
||||
v.numbers = append(v.numbers, number)
|
||||
v.nextFlush = append(v.nextFlush, 0)
|
||||
v.dirty = true
|
||||
func (l *AckList) Add(number uint32, timestamp uint32) {
|
||||
l.timestamps = append(l.timestamps, timestamp)
|
||||
l.numbers = append(l.numbers, number)
|
||||
l.nextFlush = append(l.nextFlush, 0)
|
||||
l.dirty = true
|
||||
}
|
||||
|
||||
func (v *AckList) Clear(una uint32) {
|
||||
func (l *AckList) Clear(una uint32) {
|
||||
count := 0
|
||||
for i := 0; i < len(v.numbers); i++ {
|
||||
if v.numbers[i] < una {
|
||||
for i := 0; i < len(l.numbers); i++ {
|
||||
if l.numbers[i] < una {
|
||||
continue
|
||||
}
|
||||
if i != count {
|
||||
v.numbers[count] = v.numbers[i]
|
||||
v.timestamps[count] = v.timestamps[i]
|
||||
v.nextFlush[count] = v.nextFlush[i]
|
||||
l.numbers[count] = l.numbers[i]
|
||||
l.timestamps[count] = l.timestamps[i]
|
||||
l.nextFlush[count] = l.nextFlush[i]
|
||||
}
|
||||
count++
|
||||
}
|
||||
if count < len(v.numbers) {
|
||||
v.numbers = v.numbers[:count]
|
||||
v.timestamps = v.timestamps[:count]
|
||||
v.nextFlush = v.nextFlush[:count]
|
||||
v.dirty = true
|
||||
if count < len(l.numbers) {
|
||||
l.numbers = l.numbers[:count]
|
||||
l.timestamps = l.timestamps[:count]
|
||||
l.nextFlush = l.nextFlush[:count]
|
||||
l.dirty = true
|
||||
}
|
||||
}
|
||||
|
||||
func (v *AckList) Flush(current uint32, rto uint32) {
|
||||
v.flushCandidates = v.flushCandidates[:0]
|
||||
func (l *AckList) Flush(current uint32, rto uint32) {
|
||||
l.flushCandidates = l.flushCandidates[:0]
|
||||
|
||||
seg := NewAckSegment()
|
||||
for i := 0; i < len(v.numbers); i++ {
|
||||
if v.nextFlush[i] > current {
|
||||
if len(v.flushCandidates) < cap(v.flushCandidates) {
|
||||
v.flushCandidates = append(v.flushCandidates, v.numbers[i])
|
||||
for i := 0; i < len(l.numbers); i++ {
|
||||
if l.nextFlush[i] > current {
|
||||
if len(l.flushCandidates) < cap(l.flushCandidates) {
|
||||
l.flushCandidates = append(l.flushCandidates, l.numbers[i])
|
||||
}
|
||||
continue
|
||||
}
|
||||
seg.PutNumber(v.numbers[i])
|
||||
seg.PutTimestamp(v.timestamps[i])
|
||||
seg.PutNumber(l.numbers[i])
|
||||
seg.PutTimestamp(l.timestamps[i])
|
||||
timeout := rto / 2
|
||||
if timeout < 20 {
|
||||
timeout = 20
|
||||
}
|
||||
v.nextFlush[i] = current + timeout
|
||||
l.nextFlush[i] = current + timeout
|
||||
|
||||
if seg.IsFull() {
|
||||
v.writer.Write(seg)
|
||||
l.writer.Write(seg)
|
||||
seg.Release()
|
||||
seg = NewAckSegment()
|
||||
v.dirty = false
|
||||
l.dirty = false
|
||||
}
|
||||
}
|
||||
if v.dirty || !seg.IsEmpty() {
|
||||
for _, number := range v.flushCandidates {
|
||||
if l.dirty || !seg.IsEmpty() {
|
||||
for _, number := range l.flushCandidates {
|
||||
if seg.IsFull() {
|
||||
break
|
||||
}
|
||||
seg.PutNumber(number)
|
||||
}
|
||||
v.writer.Write(seg)
|
||||
l.writer.Write(seg)
|
||||
seg.Release()
|
||||
v.dirty = false
|
||||
l.dirty = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,47 +53,47 @@ func NewDataSegment() *DataSegment {
|
||||
return new(DataSegment)
|
||||
}
|
||||
|
||||
func (v *DataSegment) Conversation() uint16 {
|
||||
return v.Conv
|
||||
func (s *DataSegment) Conversation() uint16 {
|
||||
return s.Conv
|
||||
}
|
||||
|
||||
func (v *DataSegment) Command() Command {
|
||||
func (*DataSegment) Command() Command {
|
||||
return CommandData
|
||||
}
|
||||
|
||||
func (v *DataSegment) Detach() *buf.Buffer {
|
||||
r := v.payload
|
||||
v.payload = nil
|
||||
func (s *DataSegment) Detach() *buf.Buffer {
|
||||
r := s.payload
|
||||
s.payload = nil
|
||||
return r
|
||||
}
|
||||
|
||||
func (v *DataSegment) Data() *buf.Buffer {
|
||||
if v.payload == nil {
|
||||
v.payload = buf.New()
|
||||
func (s *DataSegment) Data() *buf.Buffer {
|
||||
if s.payload == nil {
|
||||
s.payload = buf.New()
|
||||
}
|
||||
return v.payload
|
||||
return s.payload
|
||||
}
|
||||
|
||||
func (v *DataSegment) Bytes() buf.Supplier {
|
||||
func (s *DataSegment) Bytes() buf.Supplier {
|
||||
return func(b []byte) (int, error) {
|
||||
b = serial.Uint16ToBytes(v.Conv, b[:0])
|
||||
b = append(b, byte(CommandData), byte(v.Option))
|
||||
b = serial.Uint32ToBytes(v.Timestamp, b)
|
||||
b = serial.Uint32ToBytes(v.Number, b)
|
||||
b = serial.Uint32ToBytes(v.SendingNext, b)
|
||||
b = serial.Uint16ToBytes(uint16(v.payload.Len()), b)
|
||||
b = append(b, v.payload.Bytes()...)
|
||||
b = serial.Uint16ToBytes(s.Conv, b[:0])
|
||||
b = append(b, byte(CommandData), byte(s.Option))
|
||||
b = serial.Uint32ToBytes(s.Timestamp, b)
|
||||
b = serial.Uint32ToBytes(s.Number, b)
|
||||
b = serial.Uint32ToBytes(s.SendingNext, b)
|
||||
b = serial.Uint16ToBytes(uint16(s.payload.Len()), b)
|
||||
b = append(b, s.payload.Bytes()...)
|
||||
return len(b), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (v *DataSegment) ByteSize() int {
|
||||
return 2 + 1 + 1 + 4 + 4 + 4 + 2 + v.payload.Len()
|
||||
func (s *DataSegment) ByteSize() int {
|
||||
return 2 + 1 + 1 + 4 + 4 + 4 + 2 + s.payload.Len()
|
||||
}
|
||||
|
||||
func (v *DataSegment) Release() {
|
||||
v.payload.Release()
|
||||
v.payload = nil
|
||||
func (s *DataSegment) Release() {
|
||||
s.payload.Release()
|
||||
s.payload = nil
|
||||
}
|
||||
|
||||
type AckSegment struct {
|
||||
@ -113,54 +113,54 @@ func NewAckSegment() *AckSegment {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *AckSegment) Conversation() uint16 {
|
||||
return v.Conv
|
||||
func (s *AckSegment) Conversation() uint16 {
|
||||
return s.Conv
|
||||
}
|
||||
|
||||
func (v *AckSegment) Command() Command {
|
||||
func (*AckSegment) Command() Command {
|
||||
return CommandACK
|
||||
}
|
||||
|
||||
func (v *AckSegment) PutTimestamp(timestamp uint32) {
|
||||
if timestamp-v.Timestamp < 0x7FFFFFFF {
|
||||
v.Timestamp = timestamp
|
||||
func (s *AckSegment) PutTimestamp(timestamp uint32) {
|
||||
if timestamp-s.Timestamp < 0x7FFFFFFF {
|
||||
s.Timestamp = timestamp
|
||||
}
|
||||
}
|
||||
|
||||
func (v *AckSegment) PutNumber(number uint32) {
|
||||
v.NumberList = append(v.NumberList, number)
|
||||
func (s *AckSegment) PutNumber(number uint32) {
|
||||
s.NumberList = append(s.NumberList, number)
|
||||
}
|
||||
|
||||
func (v *AckSegment) IsFull() bool {
|
||||
return len(v.NumberList) == ackNumberLimit
|
||||
func (s *AckSegment) IsFull() bool {
|
||||
return len(s.NumberList) == ackNumberLimit
|
||||
}
|
||||
|
||||
func (v *AckSegment) IsEmpty() bool {
|
||||
return len(v.NumberList) == 0
|
||||
func (s *AckSegment) IsEmpty() bool {
|
||||
return len(s.NumberList) == 0
|
||||
}
|
||||
|
||||
func (v *AckSegment) ByteSize() int {
|
||||
return 2 + 1 + 1 + 4 + 4 + 4 + 1 + len(v.NumberList)*4
|
||||
func (s *AckSegment) ByteSize() int {
|
||||
return 2 + 1 + 1 + 4 + 4 + 4 + 1 + len(s.NumberList)*4
|
||||
}
|
||||
|
||||
func (v *AckSegment) Bytes() buf.Supplier {
|
||||
func (s *AckSegment) Bytes() buf.Supplier {
|
||||
return func(b []byte) (int, error) {
|
||||
b = serial.Uint16ToBytes(v.Conv, b[:0])
|
||||
b = append(b, byte(CommandACK), byte(v.Option))
|
||||
b = serial.Uint32ToBytes(v.ReceivingWindow, b)
|
||||
b = serial.Uint32ToBytes(v.ReceivingNext, b)
|
||||
b = serial.Uint32ToBytes(v.Timestamp, b)
|
||||
count := byte(len(v.NumberList))
|
||||
b = serial.Uint16ToBytes(s.Conv, b[:0])
|
||||
b = append(b, byte(CommandACK), byte(s.Option))
|
||||
b = serial.Uint32ToBytes(s.ReceivingWindow, b)
|
||||
b = serial.Uint32ToBytes(s.ReceivingNext, b)
|
||||
b = serial.Uint32ToBytes(s.Timestamp, b)
|
||||
count := byte(len(s.NumberList))
|
||||
b = append(b, count)
|
||||
for _, number := range v.NumberList {
|
||||
for _, number := range s.NumberList {
|
||||
b = serial.Uint32ToBytes(number, b)
|
||||
}
|
||||
return v.ByteSize(), nil
|
||||
return s.ByteSize(), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (v *AckSegment) Release() {
|
||||
v.NumberList = nil
|
||||
func (s *AckSegment) Release() {
|
||||
s.NumberList = nil
|
||||
}
|
||||
|
||||
type CmdOnlySegment struct {
|
||||
@ -168,7 +168,7 @@ type CmdOnlySegment struct {
|
||||
Cmd Command
|
||||
Option SegmentOption
|
||||
SendingNext uint32
|
||||
ReceivinNext uint32
|
||||
ReceivingNext uint32
|
||||
PeerRTO uint32
|
||||
}
|
||||
|
||||
@ -176,31 +176,30 @@ func NewCmdOnlySegment() *CmdOnlySegment {
|
||||
return new(CmdOnlySegment)
|
||||
}
|
||||
|
||||
func (v *CmdOnlySegment) Conversation() uint16 {
|
||||
return v.Conv
|
||||
func (s *CmdOnlySegment) Conversation() uint16 {
|
||||
return s.Conv
|
||||
}
|
||||
|
||||
func (v *CmdOnlySegment) Command() Command {
|
||||
return v.Cmd
|
||||
func (s *CmdOnlySegment) Command() Command {
|
||||
return s.Cmd
|
||||
}
|
||||
|
||||
func (v *CmdOnlySegment) ByteSize() int {
|
||||
func (*CmdOnlySegment) ByteSize() int {
|
||||
return 2 + 1 + 1 + 4 + 4 + 4
|
||||
}
|
||||
|
||||
func (v *CmdOnlySegment) Bytes() buf.Supplier {
|
||||
func (s *CmdOnlySegment) Bytes() buf.Supplier {
|
||||
return func(b []byte) (int, error) {
|
||||
b = serial.Uint16ToBytes(v.Conv, b[:0])
|
||||
b = append(b, byte(v.Cmd), byte(v.Option))
|
||||
b = serial.Uint32ToBytes(v.SendingNext, b)
|
||||
b = serial.Uint32ToBytes(v.ReceivinNext, b)
|
||||
b = serial.Uint32ToBytes(v.PeerRTO, b)
|
||||
b = serial.Uint16ToBytes(s.Conv, b[:0])
|
||||
b = append(b, byte(s.Cmd), byte(s.Option))
|
||||
b = serial.Uint32ToBytes(s.SendingNext, b)
|
||||
b = serial.Uint32ToBytes(s.ReceivingNext, b)
|
||||
b = serial.Uint32ToBytes(s.PeerRTO, b)
|
||||
return len(b), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (v *CmdOnlySegment) Release() {
|
||||
}
|
||||
func (*CmdOnlySegment) Release() {}
|
||||
|
||||
func ReadSegment(buf []byte) (Segment, []byte) {
|
||||
if len(buf) < 4 {
|
||||
@ -286,7 +285,7 @@ func ReadSegment(buf []byte) (Segment, []byte) {
|
||||
seg.SendingNext = serial.BytesToUint32(buf)
|
||||
buf = buf[4:]
|
||||
|
||||
seg.ReceivinNext = serial.BytesToUint32(buf)
|
||||
seg.ReceivingNext = serial.BytesToUint32(buf)
|
||||
buf = buf[4:]
|
||||
|
||||
seg.PeerRTO = serial.BytesToUint32(buf)
|
||||
|
@ -104,7 +104,7 @@ func TestCmdSegment(t *testing.T) {
|
||||
Cmd: CommandPing,
|
||||
Option: SegmentOptionClose,
|
||||
SendingNext: 11,
|
||||
ReceivinNext: 13,
|
||||
ReceivingNext: 13,
|
||||
PeerRTO: 15,
|
||||
}
|
||||
|
||||
@ -120,6 +120,6 @@ func TestCmdSegment(t *testing.T) {
|
||||
assert(byte(seg2.Command()), Equals, byte(seg.Command()))
|
||||
assert(byte(seg2.Option), Equals, byte(seg.Option))
|
||||
assert(seg2.SendingNext, Equals, seg.SendingNext)
|
||||
assert(seg2.ReceivinNext, Equals, seg.ReceivinNext)
|
||||
assert(seg2.ReceivingNext, Equals, seg.ReceivingNext)
|
||||
assert(seg2.PeerRTO, Equals, seg.PeerRTO)
|
||||
}
|
||||
|
@ -209,59 +209,59 @@ func NewSendingWorker(kcp *Connection) *SendingWorker {
|
||||
return worker
|
||||
}
|
||||
|
||||
func (v *SendingWorker) Release() {
|
||||
v.Lock()
|
||||
v.window.Release()
|
||||
v.Unlock()
|
||||
func (w *SendingWorker) Release() {
|
||||
w.Lock()
|
||||
w.window.Release()
|
||||
w.Unlock()
|
||||
}
|
||||
|
||||
func (v *SendingWorker) ProcessReceivingNext(nextNumber uint32) {
|
||||
v.Lock()
|
||||
defer v.Unlock()
|
||||
func (w *SendingWorker) ProcessReceivingNext(nextNumber uint32) {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
v.ProcessReceivingNextWithoutLock(nextNumber)
|
||||
w.ProcessReceivingNextWithoutLock(nextNumber)
|
||||
}
|
||||
|
||||
func (v *SendingWorker) ProcessReceivingNextWithoutLock(nextNumber uint32) {
|
||||
v.window.Clear(nextNumber)
|
||||
v.FindFirstUnacknowledged()
|
||||
func (w *SendingWorker) ProcessReceivingNextWithoutLock(nextNumber uint32) {
|
||||
w.window.Clear(nextNumber)
|
||||
w.FindFirstUnacknowledged()
|
||||
}
|
||||
|
||||
func (v *SendingWorker) FindFirstUnacknowledged() {
|
||||
first := v.firstUnacknowledged
|
||||
if !v.window.IsEmpty() {
|
||||
v.firstUnacknowledged = v.window.FirstNumber()
|
||||
func (w *SendingWorker) FindFirstUnacknowledged() {
|
||||
first := w.firstUnacknowledged
|
||||
if !w.window.IsEmpty() {
|
||||
w.firstUnacknowledged = w.window.FirstNumber()
|
||||
} else {
|
||||
v.firstUnacknowledged = v.nextNumber
|
||||
w.firstUnacknowledged = w.nextNumber
|
||||
}
|
||||
if first != v.firstUnacknowledged {
|
||||
v.firstUnacknowledgedUpdated = true
|
||||
if first != w.firstUnacknowledged {
|
||||
w.firstUnacknowledgedUpdated = true
|
||||
}
|
||||
}
|
||||
|
||||
func (v *SendingWorker) processAck(number uint32) bool {
|
||||
func (w *SendingWorker) processAck(number uint32) bool {
|
||||
// number < v.firstUnacknowledged || number >= v.nextNumber
|
||||
if number-v.firstUnacknowledged > 0x7FFFFFFF || number-v.nextNumber < 0x7FFFFFFF {
|
||||
if number-w.firstUnacknowledged > 0x7FFFFFFF || number-w.nextNumber < 0x7FFFFFFF {
|
||||
return false
|
||||
}
|
||||
|
||||
removed := v.window.Remove(number - v.firstUnacknowledged)
|
||||
removed := w.window.Remove(number - w.firstUnacknowledged)
|
||||
if removed {
|
||||
v.FindFirstUnacknowledged()
|
||||
w.FindFirstUnacknowledged()
|
||||
}
|
||||
return removed
|
||||
}
|
||||
|
||||
func (v *SendingWorker) ProcessSegment(current uint32, seg *AckSegment, rto uint32) {
|
||||
func (w *SendingWorker) ProcessSegment(current uint32, seg *AckSegment, rto uint32) {
|
||||
defer seg.Release()
|
||||
|
||||
v.Lock()
|
||||
defer v.Unlock()
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
if v.remoteNextNumber < seg.ReceivingWindow {
|
||||
v.remoteNextNumber = seg.ReceivingWindow
|
||||
if w.remoteNextNumber < seg.ReceivingWindow {
|
||||
w.remoteNextNumber = seg.ReceivingWindow
|
||||
}
|
||||
v.ProcessReceivingNextWithoutLock(seg.ReceivingNext)
|
||||
w.ProcessReceivingNextWithoutLock(seg.ReceivingNext)
|
||||
|
||||
if seg.IsEmpty() {
|
||||
return
|
||||
@ -270,7 +270,7 @@ func (v *SendingWorker) ProcessSegment(current uint32, seg *AckSegment, rto uint
|
||||
var maxack uint32
|
||||
var maxackRemoved bool
|
||||
for _, number := range seg.NumberList {
|
||||
removed := v.processAck(number)
|
||||
removed := w.processAck(number)
|
||||
if maxack < number {
|
||||
maxack = number
|
||||
maxackRemoved = removed
|
||||
@ -278,100 +278,100 @@ func (v *SendingWorker) ProcessSegment(current uint32, seg *AckSegment, rto uint
|
||||
}
|
||||
|
||||
if maxackRemoved {
|
||||
v.window.HandleFastAck(maxack, rto)
|
||||
w.window.HandleFastAck(maxack, rto)
|
||||
if current-seg.Timestamp < 10000 {
|
||||
v.conn.roundTrip.Update(current-seg.Timestamp, current)
|
||||
w.conn.roundTrip.Update(current-seg.Timestamp, current)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (v *SendingWorker) Push(f buf.Supplier) bool {
|
||||
v.Lock()
|
||||
defer v.Unlock()
|
||||
func (w *SendingWorker) Push(f buf.Supplier) bool {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
if v.window.IsFull() {
|
||||
if w.window.IsFull() {
|
||||
return false
|
||||
}
|
||||
|
||||
b := v.window.Push(v.nextNumber)
|
||||
v.nextNumber++
|
||||
b := w.window.Push(w.nextNumber)
|
||||
w.nextNumber++
|
||||
common.Must(b.Reset(f))
|
||||
return true
|
||||
}
|
||||
|
||||
func (v *SendingWorker) Write(seg Segment) error {
|
||||
func (w *SendingWorker) Write(seg Segment) error {
|
||||
dataSeg := seg.(*DataSegment)
|
||||
|
||||
dataSeg.Conv = v.conn.meta.Conversation
|
||||
dataSeg.SendingNext = v.firstUnacknowledged
|
||||
dataSeg.Conv = w.conn.meta.Conversation
|
||||
dataSeg.SendingNext = w.firstUnacknowledged
|
||||
dataSeg.Option = 0
|
||||
if v.conn.State() == StateReadyToClose {
|
||||
if w.conn.State() == StateReadyToClose {
|
||||
dataSeg.Option = SegmentOptionClose
|
||||
}
|
||||
|
||||
return v.conn.output.Write(dataSeg)
|
||||
return w.conn.output.Write(dataSeg)
|
||||
}
|
||||
|
||||
func (v *SendingWorker) OnPacketLoss(lossRate uint32) {
|
||||
if !v.conn.Config.Congestion || v.conn.roundTrip.Timeout() == 0 {
|
||||
func (w *SendingWorker) OnPacketLoss(lossRate uint32) {
|
||||
if !w.conn.Config.Congestion || w.conn.roundTrip.Timeout() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if lossRate >= 15 {
|
||||
v.controlWindow = 3 * v.controlWindow / 4
|
||||
w.controlWindow = 3 * w.controlWindow / 4
|
||||
} else if lossRate <= 5 {
|
||||
v.controlWindow += v.controlWindow / 4
|
||||
w.controlWindow += w.controlWindow / 4
|
||||
}
|
||||
if v.controlWindow < 16 {
|
||||
v.controlWindow = 16
|
||||
if w.controlWindow < 16 {
|
||||
w.controlWindow = 16
|
||||
}
|
||||
if v.controlWindow > 2*v.conn.Config.GetSendingInFlightSize() {
|
||||
v.controlWindow = 2 * v.conn.Config.GetSendingInFlightSize()
|
||||
if w.controlWindow > 2*w.conn.Config.GetSendingInFlightSize() {
|
||||
w.controlWindow = 2 * w.conn.Config.GetSendingInFlightSize()
|
||||
}
|
||||
}
|
||||
|
||||
func (v *SendingWorker) Flush(current uint32) {
|
||||
v.Lock()
|
||||
func (w *SendingWorker) Flush(current uint32) {
|
||||
w.Lock()
|
||||
|
||||
cwnd := v.firstUnacknowledged + v.conn.Config.GetSendingInFlightSize()
|
||||
if cwnd > v.remoteNextNumber {
|
||||
cwnd = v.remoteNextNumber
|
||||
cwnd := w.firstUnacknowledged + w.conn.Config.GetSendingInFlightSize()
|
||||
if cwnd > w.remoteNextNumber {
|
||||
cwnd = w.remoteNextNumber
|
||||
}
|
||||
if v.conn.Config.Congestion && cwnd > v.firstUnacknowledged+v.controlWindow {
|
||||
cwnd = v.firstUnacknowledged + v.controlWindow
|
||||
if w.conn.Config.Congestion && cwnd > w.firstUnacknowledged+w.controlWindow {
|
||||
cwnd = w.firstUnacknowledged + w.controlWindow
|
||||
}
|
||||
|
||||
if !v.window.IsEmpty() {
|
||||
v.window.Flush(current, v.conn.roundTrip.Timeout(), cwnd)
|
||||
v.firstUnacknowledgedUpdated = false
|
||||
if !w.window.IsEmpty() {
|
||||
w.window.Flush(current, w.conn.roundTrip.Timeout(), cwnd)
|
||||
w.firstUnacknowledgedUpdated = false
|
||||
}
|
||||
|
||||
updated := v.firstUnacknowledgedUpdated
|
||||
v.firstUnacknowledgedUpdated = false
|
||||
updated := w.firstUnacknowledgedUpdated
|
||||
w.firstUnacknowledgedUpdated = false
|
||||
|
||||
v.Unlock()
|
||||
w.Unlock()
|
||||
|
||||
if updated {
|
||||
v.conn.Ping(current, CommandPing)
|
||||
w.conn.Ping(current, CommandPing)
|
||||
}
|
||||
}
|
||||
|
||||
func (v *SendingWorker) CloseWrite() {
|
||||
v.Lock()
|
||||
defer v.Unlock()
|
||||
func (w *SendingWorker) CloseWrite() {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
v.window.Clear(0xFFFFFFFF)
|
||||
w.window.Clear(0xFFFFFFFF)
|
||||
}
|
||||
|
||||
func (v *SendingWorker) IsEmpty() bool {
|
||||
v.RLock()
|
||||
defer v.RUnlock()
|
||||
func (w *SendingWorker) IsEmpty() bool {
|
||||
w.RLock()
|
||||
defer w.RUnlock()
|
||||
|
||||
return v.window.IsEmpty()
|
||||
return w.window.IsEmpty()
|
||||
}
|
||||
|
||||
func (v *SendingWorker) UpdateNecessary() bool {
|
||||
return !v.IsEmpty()
|
||||
func (w *SendingWorker) UpdateNecessary() bool {
|
||||
return !w.IsEmpty()
|
||||
}
|
||||
|
||||
func (w *SendingWorker) FirstUnacknowledged() uint32 {
|
||||
|
Loading…
Reference in New Issue
Block a user