-
-
Notifications
You must be signed in to change notification settings - Fork 35
/
send.go
72 lines (64 loc) · 1.33 KB
/
send.go
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
package utp
import (
"log"
"time"
"github.com/anacrolix/missinggo"
)
type send struct {
acked missinggo.Event
payloadSize uint32
started missinggo.MonotonicTime
_type st
connID uint16
payload []byte
seqNr uint16
conn *Conn
acksSkipped int
resendTimer *time.Timer
numResends int
}
// first is true if this is the first time the send is acked. latency is
// calculated for the first ack.
func (s *send) Ack() (latency time.Duration, first bool) {
first = !s.acked.IsSet()
if first {
latency = missinggo.MonotonicSince(s.started)
}
if s.payload != nil {
sendBufferPool.Put(s.payload[:0:minMTU])
s.payload = nil
}
s.acked.Set()
if s.resendTimer != nil {
s.resendTimer.Stop()
s.resendTimer = nil
}
return
}
func (s *send) timedOut() {
s.conn.destroy(errAckTimeout)
}
func (s *send) timeoutResend() {
mu.Lock()
defer mu.Unlock()
if missinggo.MonotonicSince(s.started) >= writeTimeout {
s.timedOut()
return
}
if s.acked.IsSet() || s.conn.destroyed.IsSet() {
return
}
rt := s.conn.resendTimeout()
s.resend()
s.numResends++
s.resendTimer.Reset(rt * time.Duration(s.numResends))
}
func (s *send) resend() {
if s.acked.IsSet() {
return
}
err := s.conn.send(s._type, s.connID, s.payload, s.seqNr)
if err != nil {
log.Printf("error resending packet: %s", err)
}
}