|
|
@ -98,13 +98,14 @@ func (this *RountTripInfo) SmoothedTime() uint32 {
|
|
|
|
|
|
|
|
|
|
|
|
// Connection is a KCP connection over UDP.
|
|
|
|
// Connection is a KCP connection over UDP.
|
|
|
|
type Connection struct {
|
|
|
|
type Connection struct {
|
|
|
|
block Authenticator
|
|
|
|
block Authenticator
|
|
|
|
local, remote net.Addr
|
|
|
|
local, remote net.Addr
|
|
|
|
rd time.Time
|
|
|
|
rd time.Time
|
|
|
|
wd time.Time // write deadline
|
|
|
|
wd time.Time // write deadline
|
|
|
|
writer io.WriteCloser
|
|
|
|
writer io.WriteCloser
|
|
|
|
since int64
|
|
|
|
since int64
|
|
|
|
dataInputCond *sync.Cond
|
|
|
|
dataInputCond *sync.Cond
|
|
|
|
|
|
|
|
dataOutputCond *sync.Cond
|
|
|
|
|
|
|
|
|
|
|
|
conv uint16
|
|
|
|
conv uint16
|
|
|
|
state State
|
|
|
|
state State
|
|
|
@ -135,6 +136,7 @@ func NewConnection(conv uint16, writerCloser io.WriteCloser, local *net.UDPAddr,
|
|
|
|
conn.writer = writerCloser
|
|
|
|
conn.writer = writerCloser
|
|
|
|
conn.since = nowMillisec()
|
|
|
|
conn.since = nowMillisec()
|
|
|
|
conn.dataInputCond = sync.NewCond(new(sync.Mutex))
|
|
|
|
conn.dataInputCond = sync.NewCond(new(sync.Mutex))
|
|
|
|
|
|
|
|
conn.dataOutputCond = sync.NewCond(new(sync.Mutex))
|
|
|
|
|
|
|
|
|
|
|
|
authWriter := &AuthenticationWriter{
|
|
|
|
authWriter := &AuthenticationWriter{
|
|
|
|
Authenticator: block,
|
|
|
|
Authenticator: block,
|
|
|
@ -222,12 +224,25 @@ func (this *Connection) Write(b []byte) (int, error) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var timer *time.Timer
|
|
|
|
|
|
|
|
if !this.wd.IsZero() {
|
|
|
|
|
|
|
|
duration := this.wd.Sub(time.Now())
|
|
|
|
|
|
|
|
if duration <= 0 {
|
|
|
|
|
|
|
|
return totalWritten, errTimeout
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
timer = time.AfterFunc(duration, this.dataOutputCond.Signal)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.dataOutputCond.L.Lock()
|
|
|
|
|
|
|
|
this.dataOutputCond.Wait()
|
|
|
|
|
|
|
|
this.dataOutputCond.L.Unlock()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if timer != nil {
|
|
|
|
|
|
|
|
timer.Stop()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if !this.wd.IsZero() && this.wd.Before(time.Now()) {
|
|
|
|
if !this.wd.IsZero() && this.wd.Before(time.Now()) {
|
|
|
|
return totalWritten, errTimeout
|
|
|
|
return totalWritten, errTimeout
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Sending windows is 1024 for the moment. This amount is not gonna sent in 1 sec.
|
|
|
|
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -260,6 +275,7 @@ func (this *Connection) Close() error {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.dataInputCond.Broadcast()
|
|
|
|
this.dataInputCond.Broadcast()
|
|
|
|
|
|
|
|
this.dataOutputCond.Broadcast()
|
|
|
|
|
|
|
|
|
|
|
|
state := this.State()
|
|
|
|
state := this.State()
|
|
|
|
if state == StateReadyToClose ||
|
|
|
|
if state == StateReadyToClose ||
|
|
|
@ -410,6 +426,7 @@ func (this *Connection) Input(data []byte) int {
|
|
|
|
case *AckSegment:
|
|
|
|
case *AckSegment:
|
|
|
|
this.HandleOption(seg.Opt)
|
|
|
|
this.HandleOption(seg.Opt)
|
|
|
|
this.sendingWorker.ProcessSegment(current, seg)
|
|
|
|
this.sendingWorker.ProcessSegment(current, seg)
|
|
|
|
|
|
|
|
this.dataOutputCond.Signal()
|
|
|
|
case *CmdOnlySegment:
|
|
|
|
case *CmdOnlySegment:
|
|
|
|
this.HandleOption(seg.Opt)
|
|
|
|
this.HandleOption(seg.Opt)
|
|
|
|
if seg.Cmd == SegmentCommandTerminated {
|
|
|
|
if seg.Cmd == SegmentCommandTerminated {
|
|
|
|