@@ -17,6 +17,7 @@ import (
17
17
"sync/atomic"
18
18
"time"
19
19
20
+ "github.com/cenkalti/backoff/v4"
20
21
"github.com/insomniacslk/dhcp/dhcpv6"
21
22
)
22
23
@@ -52,7 +53,7 @@ type Client struct {
52
53
ifaceHWAddr net.HardwareAddr
53
54
conn net.PacketConn
54
55
timeout time.Duration
55
- retry int
56
+ retry uint64
56
57
logger logger
57
58
58
59
// bufferCap is the channel capacity for each TransactionID.
@@ -272,7 +273,7 @@ func WithLogDroppedPackets() ClientOpt {
272
273
// WithRetry configures the number of retransmissions to attempt.
273
274
//
274
275
// Default is 3.
275
- func WithRetry (r int ) ClientOpt {
276
+ func WithRetry (r uint64 ) ClientOpt {
276
277
return func (c * Client ) {
277
278
c .retry = r
278
279
}
@@ -443,7 +444,8 @@ var errDeadlineExceeded = errors.New("INTERNAL ERROR: deadline exceeded")
443
444
// If match is nil, the first packet matching the Transaction ID is returned.
444
445
func (c * Client ) SendAndRead (ctx context.Context , dest * net.UDPAddr , msg * dhcpv6.Message , match Matcher ) (* dhcpv6.Message , error ) {
445
446
var response * dhcpv6.Message
446
- err := c .retryFn (func (timeout time.Duration ) error {
447
+ timeout := c .timeout
448
+ err := backoff .Retry (func () error {
447
449
ch , rem , err := c .send (dest , msg )
448
450
if err != nil {
449
451
return err
@@ -457,6 +459,7 @@ func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, msg *dhcpv6
457
459
return ErrNoResponse
458
460
459
461
case <- time .After (timeout ):
462
+ timeout *= 2
460
463
return errDeadlineExceeded
461
464
462
465
case <- ctx .Done ():
@@ -470,7 +473,7 @@ func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, msg *dhcpv6
470
473
}
471
474
}
472
475
}
473
- })
476
+ }, backoff . WithContext ( backoff . WithMaxRetries ( backoff . NewExponentialBackOff (), c . retry ), ctx ) )
474
477
if err == errDeadlineExceeded {
475
478
return nil , ErrNoResponse
476
479
}
@@ -479,25 +482,3 @@ func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, msg *dhcpv6
479
482
}
480
483
return response , nil
481
484
}
482
-
483
- func (c * Client ) retryFn (fn func (timeout time.Duration ) error ) error {
484
- timeout := c .timeout
485
-
486
- // Each retry takes the amount of timeout at worst.
487
- for i := 0 ; i < c .retry || c .retry < 0 ; i ++ {
488
- switch err := fn (timeout ); err {
489
- case nil :
490
- // Got it!
491
- return nil
492
-
493
- case errDeadlineExceeded :
494
- // Double timeout, then retry.
495
- timeout *= 2
496
-
497
- default :
498
- return err
499
- }
500
- }
501
-
502
- return errDeadlineExceeded
503
- }
0 commit comments