@@ -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,7 @@ 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
+ err := backoff . Retry (func () error {
447
448
ch , rem , err := c .send (dest , msg )
448
449
if err != nil {
449
450
return err
@@ -456,7 +457,7 @@ func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, msg *dhcpv6
456
457
case <- c .done :
457
458
return ErrNoResponse
458
459
459
- case <- time .After (timeout ):
460
+ case <- time .After (c . timeout ):
460
461
return errDeadlineExceeded
461
462
462
463
case <- ctx .Done ():
@@ -470,7 +471,7 @@ func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, msg *dhcpv6
470
471
}
471
472
}
472
473
}
473
- })
474
+ }, backoff . WithMaxRetries ( backoff . NewExponentialBackOff (), c . retry ) )
474
475
if err == errDeadlineExceeded {
475
476
return nil , ErrNoResponse
476
477
}
@@ -479,25 +480,3 @@ func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, msg *dhcpv6
479
480
}
480
481
return response , nil
481
482
}
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