5
5
"errors"
6
6
"fmt"
7
7
"io"
8
- "math"
9
8
"sync"
10
9
"time"
11
10
@@ -41,10 +40,6 @@ type GoBackNConn struct {
41
40
recvDataChan chan * PacketData
42
41
sendDataChan chan * PacketData
43
42
44
- sendTimeout time.Duration
45
- recvTimeout time.Duration
46
- timeoutsMu sync.RWMutex
47
-
48
43
log btclog.Logger
49
44
50
45
// receivedACKSignal channel is used to signal that the queue size has
@@ -65,6 +60,10 @@ type GoBackNConn struct {
65
60
// remoteClosed is closed if the remote party initiated the FIN sequence.
66
61
remoteClosed chan struct {}
67
62
63
+ // timeoutManager is used to manage all the timeouts used by the
64
+ // GoBackNConn.
65
+ timeoutManager * TimeoutManager
66
+
68
67
// quit is used to stop the normal operations of the connection.
69
68
// Once closed, the send and receive streams will still be available
70
69
// for the FIN sequence.
@@ -84,63 +83,62 @@ func newGoBackNConn(ctx context.Context, cfg *config,
84
83
prefix := fmt .Sprintf ("(%s)" , loggerPrefix )
85
84
plog := build .NewPrefixLog (prefix , log )
86
85
86
+ timeoutManager := NewTimeOutManager (plog )
87
+
87
88
g := & GoBackNConn {
88
89
cfg : cfg ,
89
90
recvDataChan : make (chan * PacketData , cfg .n ),
90
91
sendDataChan : make (chan * PacketData ),
91
- recvTimeout : DefaultRecvTimeout ,
92
- sendTimeout : DefaultSendTimeout ,
93
92
receivedACKSignal : make (chan struct {}),
94
93
resendSignal : make (chan struct {}, 1 ),
95
94
remoteClosed : make (chan struct {}),
96
95
ctx : ctxc ,
97
96
cancel : cancel ,
98
97
log : plog ,
99
98
quit : make (chan struct {}),
99
+ timeoutManager : timeoutManager ,
100
100
}
101
101
102
- g .sendQueue = newQueue (& queueCfg {
103
- s : cfg .n + 1 ,
104
- timeout : cfg .resendTimeout ,
105
- log : plog ,
106
- sendPkt : func (packet * PacketData ) error {
107
- return g .sendPacket (g .ctx , packet )
102
+ g .sendQueue = newQueue (
103
+ & queueCfg {
104
+ s : cfg .n + 1 ,
105
+ log : plog ,
106
+ sendPkt : func (packet * PacketData ) error {
107
+ return g .sendPacket (g .ctx , packet )
108
+ },
108
109
},
109
- })
110
+ timeoutManager ,
111
+ )
110
112
111
113
return g
112
114
}
113
115
114
- // setN sets the current N to use. This _must_ be set before the handshake is
115
- // completed.
116
- func (g * GoBackNConn ) setN (n uint8 ) {
117
- g .cfg .n = n
118
- g .cfg .s = n + 1
119
- g .recvDataChan = make (chan * PacketData , n )
120
- g .sendQueue = newQueue (& queueCfg {
121
- s : n + 1 ,
122
- timeout : g .cfg .resendTimeout ,
123
- log : g .log ,
124
- sendPkt : func (packet * PacketData ) error {
125
- return g .sendPacket (g .ctx , packet )
126
- },
127
- })
128
- }
129
-
130
116
// SetSendTimeout sets the timeout used in the Send function.
131
117
func (g * GoBackNConn ) SetSendTimeout (timeout time.Duration ) {
132
- g .timeoutsMu .Lock ()
133
- defer g .timeoutsMu .Unlock ()
134
-
135
- g .sendTimeout = timeout
118
+ g .timeoutManager .SetSendTimeout (timeout )
136
119
}
137
120
138
121
// SetRecvTimeout sets the timeout used in the Recv function.
139
122
func (g * GoBackNConn ) SetRecvTimeout (timeout time.Duration ) {
140
- g .timeoutsMu . Lock ( )
141
- defer g . timeoutsMu . Unlock ()
123
+ g .timeoutManager . SetRecvTimeout ( timeout )
124
+ }
142
125
143
- g .recvTimeout = timeout
126
+ // setN sets the current N to use. This _must_ be set before the handshake is
127
+ // completed.
128
+ func (g * GoBackNConn ) setN (n uint8 ) {
129
+ g .cfg .n = n
130
+ g .cfg .s = n + 1
131
+ g .recvDataChan = make (chan * PacketData , n )
132
+ g .sendQueue = newQueue (
133
+ & queueCfg {
134
+ s : n + 1 ,
135
+ log : g .log ,
136
+ sendPkt : func (packet * PacketData ) error {
137
+ return g .sendPacket (g .ctx , packet )
138
+ },
139
+ },
140
+ g .timeoutManager ,
141
+ )
144
142
}
145
143
146
144
// Send blocks until an ack is received for the packet sent N packets before.
@@ -152,9 +150,7 @@ func (g *GoBackNConn) Send(data []byte) error {
152
150
default :
153
151
}
154
152
155
- g .timeoutsMu .RLock ()
156
- ticker := time .NewTimer (g .sendTimeout )
157
- g .timeoutsMu .RUnlock ()
153
+ ticker := time .NewTimer (g .timeoutManager .GetSendTimeout ())
158
154
defer ticker .Stop ()
159
155
160
156
sendPacket := func (packet * PacketData ) error {
@@ -216,9 +212,7 @@ func (g *GoBackNConn) Recv() ([]byte, error) {
216
212
msg * PacketData
217
213
)
218
214
219
- g .timeoutsMu .RLock ()
220
- ticker := time .NewTimer (g .recvTimeout )
221
- g .timeoutsMu .RUnlock ()
215
+ ticker := time .NewTimer (g .timeoutManager .GetRecvTimeout ())
222
216
defer ticker .Stop ()
223
217
224
218
for {
@@ -245,22 +239,16 @@ func (g *GoBackNConn) Recv() ([]byte, error) {
245
239
func (g * GoBackNConn ) start () {
246
240
g .log .Debugf ("Starting" )
247
241
248
- pingTime := time .Duration (math .MaxInt64 )
249
- if g .cfg .pingTime != 0 {
250
- pingTime = g .cfg .pingTime
251
- }
252
-
253
- g .pingTicker = NewIntervalAwareForceTicker (pingTime )
242
+ g .pingTicker = NewIntervalAwareForceTicker (
243
+ g .timeoutManager .GetPingTime (),
244
+ )
254
245
g .pingTicker .Resume ()
255
246
256
- pongTime := time .Duration (math .MaxInt64 )
257
- if g .cfg .pongTime != 0 {
258
- pongTime = g .cfg .pongTime
259
- }
260
-
261
- g .pongTicker = NewIntervalAwareForceTicker (pongTime )
247
+ g .pongTicker = NewIntervalAwareForceTicker (
248
+ g .timeoutManager .GetPongTime (),
249
+ )
262
250
263
- g .resendTicker = time .NewTicker (g .cfg . resendTimeout )
251
+ g .resendTicker = time .NewTicker (g .timeoutManager . GetResendTimeout () )
264
252
265
253
g .wg .Add (1 )
266
254
go func () {
@@ -317,7 +305,7 @@ func (g *GoBackNConn) Close() error {
317
305
g .log .Tracef ("Try sending FIN" )
318
306
319
307
ctxc , cancel := context .WithTimeout (
320
- g .ctx , defaultFinSendTimeout ,
308
+ g .ctx , g . timeoutManager . GetFinSendTimeout () ,
321
309
)
322
310
defer cancel ()
323
311
if err := g .sendPacket (ctxc , & PacketFIN {}); err != nil {
@@ -382,7 +370,7 @@ func (g *GoBackNConn) sendPacketsForever() error {
382
370
// execute. That can happen if the function was awaiting the
383
371
// expected ACK for a long time, or times out while awaiting the
384
372
// catch up.
385
- g .resendTicker .Reset (g .cfg . resendTimeout )
373
+ g .resendTicker .Reset (g .timeoutManager . GetResendTimeout () )
386
374
387
375
// Also drain the resend signal channel, as resendTicker.Reset
388
376
// doesn't drain the channel if the ticker ticked during the
@@ -509,7 +497,7 @@ func (g *GoBackNConn) receivePacketsForever() error { // nolint:gocyclo
509
497
g .pongTicker .Pause ()
510
498
}
511
499
512
- g .resendTicker .Reset (g .cfg . resendTimeout )
500
+ g .resendTicker .Reset (g .timeoutManager . GetResendTimeout () )
513
501
514
502
switch m := msg .(type ) {
515
503
case * PacketData :
@@ -567,8 +555,9 @@ func (g *GoBackNConn) receivePacketsForever() error { // nolint:gocyclo
567
555
// the resend, and therefore won't react to the
568
556
// NACK we send here in time.
569
557
sinceSent := time .Since (lastNackTime )
570
- recentlySent := sinceSent <
571
- g .cfg .resendTimeout * 2
558
+
559
+ timeout := g .timeoutManager .GetResendTimeout ()
560
+ recentlySent := sinceSent < timeout * 2
572
561
573
562
if lastNackSeq == g .recvSeq && recentlySent {
574
563
g .log .Tracef ("Recently sent NACK" )
0 commit comments