/*
  chronyd/chronyc - Programs for keeping computer clocks accurate.

 **********************************************************************
 * Copyright (C) Richard P. Curnow  1997-2003
 * Copyright (C) Miroslav Lichvar  2009, 2015-2017, 2021
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 **********************************************************************

  =======================================================================

  This module keeps a count of the number of successful accesses by
  clients, and the times of the last accesses.

  This can be used for status reporting, and (in the case of a
  server), if it needs to know which clients have made use of its data
  recently.

  */

#include "config.h"

#include "sysincl.h"

#include "array.h"
#include "clientlog.h"
#include "conf.h"
#include "local.h"
#include "memory.h"
#include "ntp.h"
#include "reports.h"
#include "util.h"
#include "logging.h"

#define MAX_SERVICES 3

typedef struct {
  IPAddr ip_addr;
  uint32_t last_hit[MAX_SERVICES];
  uint32_t hits[MAX_SERVICES];
  uint16_t drops[MAX_SERVICES];
  uint16_t tokens[MAX_SERVICES];
  int8_t rate[MAX_SERVICES];
  int8_t ntp_timeout_rate;
  uint8_t drop_flags;
} Record;

/* Hash table of records, there is a fixed number of records per slot */
static ARR_Instance records;

#define SLOT_BITS 4

/* Number of records in one slot of the hash table */
#define SLOT_SIZE (1U << SLOT_BITS)

/* Minimum number of slots */
#define MIN_SLOTS 1

/* Maximum number of slots, this is a hard limit */
#define MAX_SLOTS (1U << (24 - SLOT_BITS))

/* Number of slots in the hash table */
static unsigned int slots;

/* Maximum number of slots given memory allocation limit */
static unsigned int max_slots;

/* Times of last hits are saved as 32-bit fixed point values */
#define TS_FRAC 4
#define INVALID_TS 0

/* Static offset included in conversion to the fixed-point timestamps to
   randomise their alignment */
static uint32_t ts_offset;

/* Request rates are saved in the record as 8-bit scaled log2 values */
#define RATE_SCALE 4
#define MIN_RATE (-14 * RATE_SCALE)
#define INVALID_RATE -128

/* Response rates are controlled by token buckets.  The capacity and
   number of tokens spent on response are determined from configured
   minimum inverval between responses (in log2) and burst length. */

#define MIN_LIMIT_INTERVAL (-15 - TS_FRAC)
#define MAX_LIMIT_INTERVAL 12
#define MIN_LIMIT_BURST 1
#define MAX_LIMIT_BURST 255

static uint16_t max_tokens[MAX_SERVICES];
static uint16_t tokens_per_hit[MAX_SERVICES];

/* Reduction of token rates to avoid overflow of 16-bit counters.  Negative
   shift is used for coarse limiting with intervals shorter than -TS_FRAC. */
static int token_shift[MAX_SERVICES];

/* Rates at which responses are randomly allowed (in log2) when the
   buckets don't have enough tokens.  This is necessary in order to
   prevent an attacker sending requests with spoofed source address
   from blocking responses to the address completely. */

#define MIN_LEAK_RATE 1
#define MAX_LEAK_RATE 4

static int leak_rate[MAX_SERVICES];

/* Limit intervals in log2 */
static int limit_interval[MAX_SERVICES];

/* Flag indicating whether facility is turned on or not */
static int active;

/* RX and TX timestamp saved for clients using interleaved mode */
typedef struct {
  uint64_t rx_ts;
  uint16_t flags;
  uint16_t slew_epoch;
  int32_t tx_ts_offset;
} NtpTimestamps;

/* Flags for NTP timestamps */
#define NTPTS_DISABLED 1
#define NTPTS_VALID_TX 2

/* RX->TX map using a circular buffer with ordered timestamps */
typedef struct {
  ARR_Instance timestamps;
  uint32_t first;
  uint32_t size;
  uint32_t max_size;
  uint32_t cached_index;
  uint64_t cached_rx_ts;
  uint16_t slew_epoch;
  double slew_offset;
} NtpTimestampMap;

static NtpTimestampMap ntp_ts_map;

/* Maximum interval of NTP timestamps in future after a backward step */
#define NTPTS_FUTURE_LIMIT (1LL << 32) /* 1 second */

/* Maximum number of timestamps moved in the array to insert a new timestamp */
#define NTPTS_INSERT_LIMIT 64

/* Global statistics */
static uint32_t total_hits[MAX_SERVICES];
static uint32_t total_drops[MAX_SERVICES];
static uint32_t total_ntp_auth_hits;
static uint32_t total_ntp_interleaved_hits;
static uint32_t total_record_drops;

#define NSEC_PER_SEC 1000000000U

/* ================================================== */

static int expand_hashtable(void);
static void handle_slew(struct timespec *raw, struct timespec *cooked, double dfreq,
                        double doffset, LCL_ChangeType change_type, void *anything);

/* ================================================== */

static int
compare_ts(uint32_t x, uint32_t y)
{
  if (x == y)
    return 0;
  if (y == INVALID_TS)
    return 1;
  return (int32_t)(x - y) > 0 ? 1 : -1;
}

/* ================================================== */

static int
compare_total_hits(Record *x, Record *y)
{
  uint32_t x_hits, y_hits;
  int i;

  for (i = 0, x_hits = y_hits = 0; i < MAX_SERVICES; i++) {
    x_hits += x->hits[i];
    y_hits += y->hits[i];
  }

  return x_hits > y_hits ? 1 : -1;
}

/* ================================================== */

static Record *
get_record(IPAddr *ip)
{
  uint32_t last_hit = 0, oldest_hit = 0;
  Record *record, *oldest_record;
  unsigned int first, i, j;

  if (!active || (ip->family != IPADDR_INET4 && ip->family != IPADDR_INET6))
    return NULL;

  while (1) {
    /* Get index of the first record in the slot */
    first = UTI_IPToHash(ip) % slots * SLOT_SIZE;

    for (i = 0, oldest_record = NULL; i < SLOT_SIZE; i++) {
      record = ARR_GetElement(records, first + i);

      if (!UTI_CompareIPs(ip, &record->ip_addr, NULL))
        return record;

      if (record->ip_addr.family == IPADDR_UNSPEC)
        break;

      for (j = 0; j < MAX_SERVICES; j++) {
        if (j == 0 || compare_ts(last_hit, record->last_hit[j]) < 0)
          last_hit = record->last_hit[j];
      }

      if (!oldest_record || compare_ts(oldest_hit, last_hit) > 0 ||
          (oldest_hit == last_hit && compare_total_hits(oldest_record, record) > 0)) {
        oldest_record = record;
        oldest_hit = last_hit;
      }
    }

    /* If the slot still has an empty record, use it */
    if (record->ip_addr.family == IPADDR_UNSPEC)
      break;

    /* Resize the table if possible and try again as the new slot may
       have some empty records */
    if (expand_hashtable())
      continue;

    /* There is no other option, replace the oldest record */
    record = oldest_record;
    total_record_drops++;
    break;
  }

  record->ip_addr = *ip;
  for (i = 0; i < MAX_SERVICES; i++)
    record->last_hit[i] = INVALID_TS;
  for (i = 0; i < MAX_SERVICES; i++)
    record->hits[i] = 0;
  for (i = 0; i < MAX_SERVICES; i++)
    record->drops[i] = 0;
  for (i = 0; i < MAX_SERVICES; i++)
    record->tokens[i] = max_tokens[i];
  for (i = 0; i < MAX_SERVICES; i++)
    record->rate[i] = INVALID_RATE;
  record->ntp_timeout_rate = INVALID_RATE;
  record->drop_flags = 0;

  return record;
}

/* ================================================== */

static int
expand_hashtable(void)
{
  ARR_Instance old_records;
  Record *old_record, *new_record;
  unsigned int i;

  old_records = records;

  if (2 * slots > max_slots)
    return 0;

  records = ARR_CreateInstance(sizeof (Record));

  slots = MAX(MIN_SLOTS, 2 * slots);
  assert(slots <= max_slots);

  ARR_SetSize(records, slots * SLOT_SIZE);

  /* Mark all new records as empty */
  for (i = 0; i < slots * SLOT_SIZE; i++) {
    new_record = ARR_GetElement(records, i);
    new_record->ip_addr.family = IPADDR_UNSPEC;
  }

  if (!old_records)
    return 1;

  /* Copy old records to the new hash table */
  for (i = 0; i < ARR_GetSize(old_records); i++) {
    old_record = ARR_GetElement(old_records, i);
    if (old_record->ip_addr.family == IPADDR_UNSPEC)
      continue;

    new_record = get_record(&old_record->ip_addr);

    assert(new_record);
    *new_record = *old_record;
  }

  ARR_DestroyInstance(old_records);

  return 1;
}

/* ================================================== */

static void
set_bucket_params(int interval, int burst, uint16_t *max_tokens,
                  uint16_t *tokens_per_packet, int *token_shift)
{
  interval = CLAMP(MIN_LIMIT_INTERVAL, interval, MAX_LIMIT_INTERVAL);
  burst = CLAMP(MIN_LIMIT_BURST, burst, MAX_LIMIT_BURST);

  if (interval >= -TS_FRAC) {
    /* Find the smallest shift with which the maximum number fits in 16 bits */
    for (*token_shift = 0; *token_shift < interval + TS_FRAC; (*token_shift)++) {
      if (burst << (TS_FRAC + interval - *token_shift) < 1U << 16)
        break;
    }
  } else {
    /* Coarse rate limiting */
    *token_shift = interval + TS_FRAC;
    *tokens_per_packet = 1;
    burst = MAX(1U << -*token_shift, burst);
  }

  *tokens_per_packet = 1U << (TS_FRAC + interval - *token_shift);
  *max_tokens = *tokens_per_packet * burst;

  DEBUG_LOG("Tokens max %d packet %d shift %d",
            *max_tokens, *tokens_per_packet, *token_shift);
}

/* ================================================== */

void
CLG_Initialise(void)
{
  int i, interval, burst, lrate, slots2;

  for (i = 0; i < MAX_SERVICES; i++) {
    max_tokens[i] = 0;
    tokens_per_hit[i] = 0;
    token_shift[i] = 0;
    leak_rate[i] = 0;
    limit_interval[i] = MIN_LIMIT_INTERVAL;

    switch (i) {
      case CLG_NTP:
        if (!CNF_GetNTPRateLimit(&interval, &burst, &lrate))
          continue;
        break;
      case CLG_NTSKE:
        if (!CNF_GetNtsRateLimit(&interval, &burst, &lrate))
          continue;
        break;
      case CLG_CMDMON:
        if (!CNF_GetCommandRateLimit(&interval, &burst, &lrate))
          continue;
        break;
      default:
        assert(0);
    }

    set_bucket_params(interval, burst, &max_tokens[i], &tokens_per_hit[i], &token_shift[i]);
    leak_rate[i] = CLAMP(MIN_LEAK_RATE, lrate, MAX_LEAK_RATE);
    limit_interval[i] = CLAMP(MIN_LIMIT_INTERVAL, interval, MAX_LIMIT_INTERVAL);
  }

  active = !CNF_GetNoClientLog();
  if (!active) {
    for (i = 0; i < MAX_SERVICES; i++) {
      if (leak_rate[i] != 0)
        LOG_FATAL("Rate limiting cannot be enabled with noclientlog");
    }
    return;
  }

  /* Calculate the maximum number of slots that can be allocated in the
     configured memory limit.  Take into account expanding of the hash
     table where two copies exist at the same time. */
  max_slots = CNF_GetClientLogLimit() /
              ((sizeof (Record) + sizeof (NtpTimestamps)) * SLOT_SIZE * 3 / 2);
  max_slots = CLAMP(MIN_SLOTS, max_slots, MAX_SLOTS);
  for (slots2 = 0; 1U << (slots2 + 1) <= max_slots; slots2++)
    ;

  DEBUG_LOG("Max records %u", 1U << (slots2 + SLOT_BITS));

  slots = 0;
  records = NULL;

  expand_hashtable();

  UTI_GetRandomBytes(&ts_offset, sizeof (ts_offset));
  ts_offset %= NSEC_PER_SEC / (1U << TS_FRAC);

  ntp_ts_map.timestamps = NULL;
  ntp_ts_map.first = 0;
  ntp_ts_map.size = 0;
  ntp_ts_map.max_size = 1U << (slots2 + SLOT_BITS);
  ntp_ts_map.cached_index = 0;
  ntp_ts_map.cached_rx_ts = 0ULL;
  ntp_ts_map.slew_epoch = 0;
  ntp_ts_map.slew_offset = 0.0;

  LCL_AddParameterChangeHandler(handle_slew, NULL);
}

/* ================================================== */

void
CLG_Finalise(void)
{
  if (!active)
    return;

  ARR_DestroyInstance(records);
  if (ntp_ts_map.timestamps)
    ARR_DestroyInstance(ntp_ts_map.timestamps);

  LCL_RemoveParameterChangeHandler(handle_slew, NULL);
}

/* ================================================== */

static uint32_t
get_ts_from_timespec(struct timespec *ts)
{
  uint32_t sec = ts->tv_sec, nsec = ts->tv_nsec;

  nsec += ts_offset;
  if (nsec >= NSEC_PER_SEC) {
    nsec -= NSEC_PER_SEC;
    sec++;
  }

  /* This is fast and accurate enough */
  return sec << TS_FRAC | (140740U * (nsec >> 15)) >> (32 - TS_FRAC);
}

/* ================================================== */

static void
update_record(CLG_Service service, Record *record, struct timespec *now)
{
  uint32_t interval, now_ts, prev_hit, tokens;
  int interval2, tshift, mtokens;
  int8_t *rate;

  now_ts = get_ts_from_timespec(now);

  prev_hit = record->last_hit[service];
  record->last_hit[service] = now_ts;
  record->hits[service]++;

  interval = now_ts - prev_hit;

  if (prev_hit == INVALID_TS || (int32_t)interval < 0)
    return;

  tshift = token_shift[service];
  mtokens = max_tokens[service];

  if (tshift >= 0)
    tokens = (now_ts >> tshift) - (prev_hit >> tshift);
  else if (now_ts - prev_hit > mtokens)
    tokens = mtokens;
  else
    tokens = (now_ts - prev_hit) << -tshift;
  record->tokens[service] = MIN(record->tokens[service] + tokens, mtokens);

  /* Convert the interval to scaled and rounded log2 */
  if (interval) {
    interval += interval >> 1;
    for (interval2 = -RATE_SCALE * TS_FRAC; interval2 < -MIN_RATE;
         interval2 += RATE_SCALE) {
      if (interval <= 1)
        break;
      interval >>= 1;
    }
  } else {
    interval2 = -RATE_SCALE * (TS_FRAC + 1);
  }

  /* For the NTP service, update one of the two rates depending on whether
     the previous request of the client had a reply or it timed out */
  rate = service == CLG_NTP && record->drop_flags & (1U << service) ?
           &record->ntp_timeout_rate : &record->rate[service];

  /* Update the rate in a rough approximation of exponential moving average */
  if (*rate == INVALID_RATE) {
    *rate = -interval2;
  } else {
    if (*rate < -interval2) {
      (*rate)++;
    } else if (*rate > -interval2) {
      if (*rate > RATE_SCALE * 5 / 2 - interval2)
        *rate = RATE_SCALE * 5 / 2 - interval2;
      else
        *rate = (*rate - interval2 - 1) / 2;
    }
  }
}

/* ================================================== */

static int
get_index(Record *record)
{
  return record - (Record *)ARR_GetElements(records);
}

/* ================================================== */

int
CLG_GetClientIndex(IPAddr *client)
{
  Record *record;

  record = get_record(client);
  if (record == NULL)
    return -1;

  return get_index(record);
}

/* ================================================== */

static void
check_service_number(CLG_Service service)
{
  assert(service >= 0 && service <= MAX_SERVICES);
}

/* ================================================== */

int
CLG_LogServiceAccess(CLG_Service service, IPAddr *client, struct timespec *now)
{
  Record *record;

  check_service_number(service);

  total_hits[service]++;

  record = get_record(client);
  if (record == NULL)
    return -1;

  update_record(service, record, now);

  DEBUG_LOG("service %d hits %"PRIu32" rate %d trate %d tokens %d",
            (int)service, record->hits[service], record->rate[service],
            service == CLG_NTP ? record->ntp_timeout_rate : INVALID_RATE,
            record->tokens[service]);

  return get_index(record);
}

/* ================================================== */

static int
limit_response_random(int leak_rate)
{
  static uint32_t rnd;
  static int bits_left = 0;
  int r;

  if (bits_left < leak_rate) {
    UTI_GetRandomBytes(&rnd, sizeof (rnd));
    bits_left = 8 * sizeof (rnd);
  }

  /* Return zero on average once per 2^leak_rate */
  r = rnd % (1U << leak_rate) ? 1 : 0;
  rnd >>= leak_rate;
  bits_left -= leak_rate;

  return r;
}

/* ================================================== */

int
CLG_LimitServiceRate(CLG_Service service, int index)
{
  Record *record;
  int drop;

  check_service_number(service);

  if (tokens_per_hit[service] == 0)
    return 0;

  record = ARR_GetElement(records, index);
  record->drop_flags &= ~(1U << service);

  if (record->tokens[service] >= tokens_per_hit[service]) {
    record->tokens[service] -= tokens_per_hit[service];
    return 0;
  }

  drop = limit_response_random(leak_rate[service]);

  /* Poorly implemented NTP clients can send requests at a higher rate
     when they are not getting replies.  If the request rate seems to be more
     than twice as much as when replies are sent, give up on rate limiting to
     reduce the amount of traffic.  Invert the sense of the leak to respond to
     most of the requests, but still keep the estimated rate updated. */
  if (service == CLG_NTP && record->ntp_timeout_rate != INVALID_RATE &&
      record->ntp_timeout_rate > record->rate[service] + RATE_SCALE)
    drop = !drop;

  if (!drop) {
    record->tokens[service] = 0;
    return 0;
  }

  record->drop_flags |= 1U << service;
  record->drops[service]++;
  total_drops[service]++;

  return 1;
}

/* ================================================== */

void
CLG_LogAuthNtpRequest(void)
{
  total_ntp_auth_hits++;
}

/* ================================================== */

int
CLG_GetNtpMinPoll(void)
{
  return limit_interval[CLG_NTP];
}

/* ================================================== */

static NtpTimestamps *
get_ntp_tss(uint32_t index)
{
  return ARR_GetElement(ntp_ts_map.timestamps,
                        (ntp_ts_map.first + index) & (ntp_ts_map.max_size - 1));
}

/* ================================================== */

static int
find_ntp_rx_ts(uint64_t rx_ts, uint32_t *index)
{
  uint64_t rx_x, rx_lo, rx_hi, step;
  uint32_t i, x, lo, hi;

  if (ntp_ts_map.cached_rx_ts == rx_ts && rx_ts != 0ULL) {
    *index = ntp_ts_map.cached_index;
    return 1;
  }

  if (ntp_ts_map.size == 0) {
    *index = 0;
    return 0;
  }

  lo = 0;
  hi = ntp_ts_map.size - 1;
  rx_lo = get_ntp_tss(lo)->rx_ts;
  rx_hi = get_ntp_tss(hi)->rx_ts;

  /* Check for ts < lo before ts > hi to trim timestamps from "future" later
     if both conditions are true to not break the order of the endpoints.
     Compare timestamps by their difference to allow adjacent NTP eras. */
  if ((int64_t)(rx_ts - rx_lo) < 0) {
    *index = 0;
    return 0;
  } else if ((int64_t)(rx_ts - rx_hi) > 0) {
    *index = ntp_ts_map.size;
    return 0;
  }

  /* Perform a combined linear interpolation and binary search */

  for (i = 0; ; i++) {
    if (rx_ts == rx_hi) {
      *index = ntp_ts_map.cached_index = hi;
      ntp_ts_map.cached_rx_ts = rx_ts;
      return 1;
    } else if (rx_ts == rx_lo) {
      *index = ntp_ts_map.cached_index = lo;
      ntp_ts_map.cached_rx_ts = rx_ts;
      return 1;
    } else if (lo + 1 == hi) {
      *index = hi;
      return 0;
    }

    if (hi - lo > 3 && i % 2 == 0) {
      step = (rx_hi - rx_lo) / (hi - lo);
      if (step == 0)
        step = 1;
      x = lo + (rx_ts - rx_lo) / step;
    } else {
      x = lo + (hi - lo) / 2;
    }

    if (x <= lo)
      x = lo + 1;
    else if (x >= hi)
      x = hi - 1;

    rx_x = get_ntp_tss(x)->rx_ts;

    if ((int64_t)(rx_x - rx_ts) <= 0) {
      lo = x;
      rx_lo = rx_x;
    } else {
      hi = x;
      rx_hi = rx_x;
    }
  }
}

/* ================================================== */

static uint64_t
ntp64_to_int64(NTP_int64 *ts)
{
  return (uint64_t)ntohl(ts->hi) << 32 | ntohl(ts->lo);
}

/* ================================================== */

static void
int64_to_ntp64(uint64_t ts, NTP_int64 *ntp_ts)
{
  ntp_ts->hi = htonl(ts >> 32);
  ntp_ts->lo = htonl(ts);
}

/* ================================================== */

static uint32_t
push_ntp_tss(uint32_t index)
{
  if (ntp_ts_map.size < ntp_ts_map.max_size) {
    ntp_ts_map.size++;
  } else {
    ntp_ts_map.first = (ntp_ts_map.first + 1) % (ntp_ts_map.max_size);
    if (index > 0)
      index--;
  }

  return index;
}

/* ================================================== */

static void
set_ntp_tx_offset(NtpTimestamps *tss, NTP_int64 *rx_ts, struct timespec *tx_ts)
{
  struct timespec ts;

  if (!tx_ts) {
    tss->flags &= ~NTPTS_VALID_TX;
    return;
  }

  UTI_Ntp64ToTimespec(rx_ts, &ts);
  UTI_DiffTimespecs(&ts, tx_ts, &ts);

  if (ts.tv_sec < -2 || ts.tv_sec > 1) {
    tss->flags &= ~NTPTS_VALID_TX;
    return;
  }

  tss->tx_ts_offset = (int32_t)ts.tv_nsec + (int32_t)ts.tv_sec * (int32_t)NSEC_PER_SEC;
  tss->flags |= NTPTS_VALID_TX;
}

/* ================================================== */

static void
get_ntp_tx(NtpTimestamps *tss, struct timespec *tx_ts)
{
  int32_t offset = tss->tx_ts_offset;
  NTP_int64 ntp_ts;

  if (tss->flags & NTPTS_VALID_TX) {
    int64_to_ntp64(tss->rx_ts, &ntp_ts);
    UTI_Ntp64ToTimespec(&ntp_ts, tx_ts);
    if (offset >= (int32_t)NSEC_PER_SEC) {
      offset -= NSEC_PER_SEC;
      tx_ts->tv_sec++;
    }
    tx_ts->tv_nsec += offset;
    UTI_NormaliseTimespec(tx_ts);
  } else {
    UTI_ZeroTimespec(tx_ts);
  }
}

/* ================================================== */

void
CLG_SaveNtpTimestamps(NTP_int64 *rx_ts, struct timespec *tx_ts)
{
  NtpTimestamps *tss;
  uint32_t i, index;
  uint64_t rx;

  if (!active)
    return;

  /* Allocate the array on first use */
  if (!ntp_ts_map.timestamps) {
    ntp_ts_map.timestamps = ARR_CreateInstance(sizeof (NtpTimestamps));
    ARR_SetSize(ntp_ts_map.timestamps, ntp_ts_map.max_size);
  }

  rx = ntp64_to_int64(rx_ts);

  if (rx == 0ULL)
    return;

  /* Disable the RX timestamp if it already exists to avoid responding
     with a wrong TX timestamp */
  if (find_ntp_rx_ts(rx, &index)) {
    get_ntp_tss(index)->flags |= NTPTS_DISABLED;
    return;
  }

  assert(index <= ntp_ts_map.size);

  if (index == ntp_ts_map.size) {
    /* Increase the size or drop the oldest timestamp to make room for
       the new timestamp */
    index = push_ntp_tss(index);
  } else {
    /* Trim timestamps in distant future after backward step */
    while (index < ntp_ts_map.size &&
           get_ntp_tss(ntp_ts_map.size - 1)->rx_ts - rx > NTPTS_FUTURE_LIMIT)
      ntp_ts_map.size--;

    /* Insert the timestamp if it is close to the latest timestamp.
       Otherwise, replace the closest older or the oldest timestamp. */
    if (index + NTPTS_INSERT_LIMIT >= ntp_ts_map.size) {
      index = push_ntp_tss(index);
      for (i = ntp_ts_map.size - 1; i > index; i--)
        *get_ntp_tss(i) = *get_ntp_tss(i - 1);
    } else {
      if (index > 0)
        index--;
    }
  }

  ntp_ts_map.cached_index = index;
  ntp_ts_map.cached_rx_ts = rx;

  tss = get_ntp_tss(index);
  tss->rx_ts = rx;
  tss->flags = 0;
  tss->slew_epoch = ntp_ts_map.slew_epoch;
  set_ntp_tx_offset(tss, rx_ts, tx_ts);

  DEBUG_LOG("Saved RX+TX index=%"PRIu32" first=%"PRIu32" size=%"PRIu32,
            index, ntp_ts_map.first, ntp_ts_map.size);
}

/* ================================================== */

static void
handle_slew(struct timespec *raw, struct timespec *cooked, double dfreq,
            double doffset, LCL_ChangeType change_type, void *anything)
{
  /* Drop all timestamps on unknown step */
  if (change_type == LCL_ChangeUnknownStep) {
    ntp_ts_map.size = 0;
    ntp_ts_map.cached_rx_ts = 0ULL;
  }

  ntp_ts_map.slew_epoch++;
  ntp_ts_map.slew_offset = doffset;
}

/* ================================================== */

void
CLG_UndoNtpTxTimestampSlew(NTP_int64 *rx_ts, struct timespec *tx_ts)
{
  uint32_t index;

  if (!ntp_ts_map.timestamps)
    return;

  if (!find_ntp_rx_ts(ntp64_to_int64(rx_ts), &index))
    return;

  /* If the RX timestamp was captured before the last correction of the clock,
     remove the adjustment from the TX timestamp */
  if ((uint16_t)(get_ntp_tss(index)->slew_epoch + 1U) == ntp_ts_map.slew_epoch)
    UTI_AddDoubleToTimespec(tx_ts, ntp_ts_map.slew_offset, tx_ts);
}

/* ================================================== */

void
CLG_UpdateNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts)
{
  uint32_t index;

  if (!ntp_ts_map.timestamps)
    return;

  if (!find_ntp_rx_ts(ntp64_to_int64(rx_ts), &index))
    return;

  set_ntp_tx_offset(get_ntp_tss(index), rx_ts, tx_ts);
}

/* ================================================== */

int
CLG_GetNtpTxTimestamp(NTP_int64 *rx_ts, struct timespec *tx_ts)
{
  NtpTimestamps *tss;
  uint32_t index;

  if (!ntp_ts_map.timestamps)
    return 0;

  if (!find_ntp_rx_ts(ntp64_to_int64(rx_ts), &index))
    return 0;

  tss = get_ntp_tss(index);

  if (tss->flags & NTPTS_DISABLED)
    return 0;

  get_ntp_tx(tss, tx_ts);

  return 1;
}

/* ================================================== */

void
CLG_DisableNtpTimestamps(NTP_int64 *rx_ts)
{
  uint32_t index;

  if (!ntp_ts_map.timestamps)
    return;

  if (find_ntp_rx_ts(ntp64_to_int64(rx_ts), &index))
    get_ntp_tss(index)->flags |= NTPTS_DISABLED;

  /* This assumes the function is called only to prevent multiple
     interleaved responses to the same timestamp */
  total_ntp_interleaved_hits++;
}

/* ================================================== */

int
CLG_GetNumberOfIndices(void)
{
  if (!active)
    return -1;

  return ARR_GetSize(records);
}

/* ================================================== */

static int get_interval(int rate)
{
  if (rate == INVALID_RATE)
    return 127;

  rate += rate > 0 ? RATE_SCALE / 2 : -RATE_SCALE / 2;

  return rate / -RATE_SCALE;
}

/* ================================================== */

static uint32_t get_last_ago(uint32_t x, uint32_t y)
{
  if (y == INVALID_TS || (int32_t)(x - y) < 0)
    return -1;

  return (x - y) >> TS_FRAC;
}

/* ================================================== */

int
CLG_GetClientAccessReportByIndex(int index, int reset, uint32_t min_hits,
                                 RPT_ClientAccessByIndex_Report *report, struct timespec *now)
{
  Record *record;
  uint32_t now_ts;
  int i, r;

  if (!active || index < 0 || index >= ARR_GetSize(records))
    return 0;

  record = ARR_GetElement(records, index);

  if (record->ip_addr.family == IPADDR_UNSPEC)
    return 0;

  if (min_hits == 0) {
    r = 1;
  } else {
    for (i = r = 0; i < MAX_SERVICES; i++) {
      if (record->hits[i] >= min_hits) {
        r = 1;
        break;
      }
    }
  }

  if (r) {
    now_ts = get_ts_from_timespec(now);

    report->ip_addr = record->ip_addr;
    report->ntp_hits = record->hits[CLG_NTP];
    report->nke_hits = record->hits[CLG_NTSKE];
    report->cmd_hits = record->hits[CLG_CMDMON];
    report->ntp_drops = record->drops[CLG_NTP];
    report->nke_drops = record->drops[CLG_NTSKE];
    report->cmd_drops = record->drops[CLG_CMDMON];
    report->ntp_interval = get_interval(record->rate[CLG_NTP]);
    report->nke_interval = get_interval(record->rate[CLG_NTSKE]);
    report->cmd_interval = get_interval(record->rate[CLG_CMDMON]);
    report->ntp_timeout_interval = get_interval(record->ntp_timeout_rate);
    report->last_ntp_hit_ago = get_last_ago(now_ts, record->last_hit[CLG_NTP]);
    report->last_nke_hit_ago = get_last_ago(now_ts, record->last_hit[CLG_NTSKE]);
    report->last_cmd_hit_ago = get_last_ago(now_ts, record->last_hit[CLG_CMDMON]);
  }

  if (reset) {
    for (i = 0; i < MAX_SERVICES; i++) {
      record->hits[i] = 0;
      record->drops[i] = 0;
    }
  }

  return r;
}

/* ================================================== */

void
CLG_GetServerStatsReport(RPT_ServerStatsReport *report)
{
  report->ntp_hits = total_hits[CLG_NTP];
  report->nke_hits = total_hits[CLG_NTSKE];
  report->cmd_hits = total_hits[CLG_CMDMON];
  report->ntp_drops = total_drops[CLG_NTP];
  report->nke_drops = total_drops[CLG_NTSKE];
  report->cmd_drops = total_drops[CLG_CMDMON];
  report->log_drops = total_record_drops;
  report->ntp_auth_hits = total_ntp_auth_hits;
  report->ntp_interleaved_hits = total_ntp_interleaved_hits;
  report->ntp_timestamps = ntp_ts_map.size;
  report->ntp_span_seconds = ntp_ts_map.size > 1 ?
                             (get_ntp_tss(ntp_ts_map.size - 1)->rx_ts -
                              get_ntp_tss(0)->rx_ts) >> 32 : 0;
}
