Skip to content

Commit

Permalink
nclient6: Use cenkalti/backoff/v4 library to replace backoff algorith…
Browse files Browse the repository at this point in the history
…m in #296

Signed-off-by: Heinz Boehmer Fiehn <[email protected]>
  • Loading branch information
heinz-boehmer committed Aug 18, 2021
1 parent d11e07c commit 44f475c
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 26 deletions.
33 changes: 7 additions & 26 deletions dhcpv6/nclient6/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"sync/atomic"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/insomniacslk/dhcp/dhcpv6"
)

Expand Down Expand Up @@ -52,7 +53,7 @@ type Client struct {
ifaceHWAddr net.HardwareAddr
conn net.PacketConn
timeout time.Duration
retry int
retry uint64
logger logger

// bufferCap is the channel capacity for each TransactionID.
Expand Down Expand Up @@ -272,7 +273,7 @@ func WithLogDroppedPackets() ClientOpt {
// WithRetry configures the number of retransmissions to attempt.
//
// Default is 3.
func WithRetry(r int) ClientOpt {
func WithRetry(r uint64) ClientOpt {
return func(c *Client) {
c.retry = r
}
Expand Down Expand Up @@ -443,7 +444,8 @@ var errDeadlineExceeded = errors.New("INTERNAL ERROR: deadline exceeded")
// If match is nil, the first packet matching the Transaction ID is returned.
func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, msg *dhcpv6.Message, match Matcher) (*dhcpv6.Message, error) {
var response *dhcpv6.Message
err := c.retryFn(func(timeout time.Duration) error {
timeout := c.timeout
err := backoff.Retry(func() error {
ch, rem, err := c.send(dest, msg)
if err != nil {
return err
Expand All @@ -457,6 +459,7 @@ func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, msg *dhcpv6
return ErrNoResponse

case <-time.After(timeout):
timeout *= 2
return errDeadlineExceeded

case <-ctx.Done():
Expand All @@ -470,7 +473,7 @@ func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, msg *dhcpv6
}
}
}
})
}, backoff.WithContext(backoff.WithMaxRetries(backoff.NewExponentialBackOff(), c.retry), ctx))
if err == errDeadlineExceeded {
return nil, ErrNoResponse
}
Expand All @@ -479,25 +482,3 @@ func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, msg *dhcpv6
}
return response, nil
}

func (c *Client) retryFn(fn func(timeout time.Duration) error) error {
timeout := c.timeout

// Each retry takes the amount of timeout at worst.
for i := 0; i < c.retry || c.retry < 0; i++ {
switch err := fn(timeout); err {
case nil:
// Got it!
return nil

case errDeadlineExceeded:
// Double timeout, then retry.
timeout *= 2

default:
return err
}
}

return errDeadlineExceeded
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/insomniacslk/dhcp
go 1.13

require (
github.com/cenkalti/backoff/v4 v4.1.1 // indirect
github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714
github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72 h1:0eU/faU2oDIB2BkQVM02hgRLJjGzzUuRf19HUhp0394=
Expand Down

0 comments on commit 44f475c

Please sign in to comment.