Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nclient6: Use cenkalti/backoff/v4 library to replace backoff algorith… #439

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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