If the system clock was stepped forward after chronyc sent a request and
before it read the clock in order to calculate the receive timeout,
select() could be called with a negative timeout, which resulted in an
infinite loop waiting for select() to succeed.
Fix the submit_request() function to not call select() with a negative
timeout. Also, return immediately on any error of select().
timeout = initial_timeout / 1000.0 * (1U << (n_attempts - 1)) -
UTI_DiffTimespecsToDouble(&ts_now, &ts_start);
- UTI_DoubleToTimeval(timeout, &tv);
DEBUG_LOG("Timeout %f seconds", timeout);
+ /* Avoid calling select() with an invalid timeout */
+ if (timeout <= 0.0) {
+ new_attempt = 1;
+ continue;
+ }
+
+ UTI_DoubleToTimeval(timeout, &tv);
+
FD_ZERO(&rdfd);
FD_ZERO(&wrfd);
FD_ZERO(&exfd);
if (select_status < 0) {
DEBUG_LOG("select failed : %s", strerror(errno));
+ return 0;
} else if (select_status == 0) {
/* Timeout must have elapsed, try a resend? */
new_attempt = 1;