- if (delayresponse && !m->SuppressSending)
- {
- // Pick a random delay between 20ms and 120ms.
- m->SuppressSending = m->timenow + (mDNSPlatformOneSecond*2 + (mDNSs32)mDNSRandom((mDNSu32)mDNSPlatformOneSecond*10)) / 100;
+ if (delayresponse && (!m->SuppressSending || (m->SuppressSending - m->timenow) < (delayresponse + 49) / 50))
+ {
+ // Pick a random delay:
+ // We start with the base delay chosen above (typically either 1 second or 20 seconds),
+ // and add a random value in the range 0-5 seconds (making 1-6 seconds or 20-25 seconds).
+ // This is an integer value, with resolution determined by the platform clock rate.
+ // We then divide that by 50 to get the delay value in ticks. We defer the division until last
+ // to get better results on platforms with coarse clock granularity (e.g. ten ticks per second).
+ // The +49 before dividing is to ensure we round up, not down, to ensure that even
+ // on platforms where the native clock rate is less than fifty ticks per second,
+ // we still guarantee that the final calculated delay is at least one platform tick.
+ // We want to make sure we don't ever allow the delay to be zero ticks,
+ // because if that happens we'll fail the Rendezvous Conformance Test.
+ // Our final computed delay is 20-120ms for normal delayed replies,
+ // or 400-500ms in the case of multi-packet known-answer lists.
+ m->SuppressSending = m->timenow + (delayresponse + (mDNSs32)mDNSRandom((mDNSu32)mDNSPlatformOneSecond*5) + 49) / 50;