Skip to content

Commit

Permalink
mixclient: Avoid jitter calculation panic
Browse files Browse the repository at this point in the history
rand.Duration may not be called with a negative or zero upper bound, but this
was seen to occur in (*Client).prDelay().  Two notable possible bugs stood out.

First, if sendBefore is exactly equal to now, then it will not be incremented
by another epoch duration, leading to a potential invalid rand.Duration
parameter.  This is corrected by also checking for the times equaling exactly.

Second, time.Until() causes an additional call to time.Now(), which we have
already fetched and all calculations must be based on it.  If
sendBefore.Sub(now) is an extremely small value, it is possible that
time.Until(sendBefore) now returns a small negative or zero duration.  This is
corrected by replacing the time.Until call with sendBefore.Sub(now).
  • Loading branch information
jrick committed Oct 15, 2024
1 parent 7735cbb commit 7faf150
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions mixing/mixclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,11 +516,11 @@ func (c *Client) prDelay(ctx context.Context, p *peer) error {
sendBefore := epoch.Add(-timeoutDuration - maxJitter)
sendAfter := epoch.Add(timeoutDuration)
var wait time.Duration
if now.After(sendBefore) {
if now.Equal(sendBefore) || now.After(sendBefore) {
wait = sendAfter.Sub(now)
sendBefore = sendBefore.Add(c.epoch)
}
wait += p.msgJitter() + rand.Duration(time.Until(sendBefore))
wait += p.msgJitter() + rand.Duration(sendBefore.Sub(now))
timer := time.NewTimer(wait)
select {
case <-ctx.Done():
Expand Down

0 comments on commit 7faf150

Please sign in to comment.