1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-27 14:26:11 -04:00

kcp cleanup

This commit is contained in:
Darien Raymond 2018-01-17 17:36:14 +01:00
parent a6c0ef11ba
commit 630a76d06a
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
6 changed files with 236 additions and 237 deletions

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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,94 +113,93 @@ 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 {
Conv uint16
Cmd Command
Option SegmentOption
SendingNext uint32
ReceivinNext uint32
PeerRTO uint32
Conv uint16
Cmd Command
Option SegmentOption
SendingNext uint32
ReceivingNext uint32
PeerRTO uint32
}
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)

View File

@ -100,12 +100,12 @@ func TestCmdSegment(t *testing.T) {
assert := With(t)
seg := &CmdOnlySegment{
Conv: 1,
Cmd: CommandPing,
Option: SegmentOptionClose,
SendingNext: 11,
ReceivinNext: 13,
PeerRTO: 15,
Conv: 1,
Cmd: CommandPing,
Option: SegmentOptionClose,
SendingNext: 11,
ReceivingNext: 13,
PeerRTO: 15,
}
nBytes := seg.ByteSize()
@ -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)
}

View File

@ -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 {