Exemple #1
0
static void
rehash_records(void)
{
  SourceRecord *temp_records;
  unsigned int i, old_size, new_size;
  int slot, found;

  old_size = ARR_GetSize(records);

  temp_records = MallocArray(SourceRecord, old_size);
  memcpy(temp_records, ARR_GetElements(records), old_size * sizeof (SourceRecord));

  /* The size of the hash table is always a power of two */
  for (new_size = 1; !check_hashtable_size(n_sources, new_size); new_size *= 2)
    ;

  ARR_SetSize(records, new_size);

  for (i = 0; i < new_size; i++)
    get_record(i)->remote_addr = NULL;

  for (i = 0; i < old_size; i++) {
    if (!temp_records[i].remote_addr)
      continue;

    find_slot(temp_records[i].remote_addr, &slot, &found);
    assert(!found);

    *get_record(slot) = temp_records[i];
  }

  Free(temp_records);
}
Exemple #2
0
int
NSR_TakeSourcesOnline(IPAddr *mask, IPAddr *address)
{
  SourceRecord *record;
  unsigned int i;
  int any;

  NSR_ResolveSources();

  any = 0;
  for (i = 0; i < ARR_GetSize(records); i++) {
    record = get_record(i);
    if (record->remote_addr) {
      if (address->family == IPADDR_UNSPEC ||
          !UTI_CompareIPs(&record->remote_addr->ip_addr, address, mask)) {
        any = 1;
        NCR_TakeSourceOnline(record->data);
      }
    }
  }

  if (address->family == IPADDR_UNSPEC) {
    struct UnresolvedSource *us;

    for (us = unresolved_sources; us; us = us->next) {
      if (us->replacement)
        continue;
      any = 1;
      us->new_source.params.online = 1;
    }
  }

  return any;
}
Exemple #3
0
void
NSR_Finalise(void)
{
  SourceRecord *record;
  struct UnresolvedSource *us;
  unsigned int i;

  ARR_DestroyInstance(pools);

  for (i = 0; i < ARR_GetSize(records); i++) {
    record = get_record(i);
    if (record->remote_addr)
      clean_source_record(record);
  }

  ARR_DestroyInstance(records);

  while (unresolved_sources) {
    us = unresolved_sources;
    unresolved_sources = us->next;
    Free(us->name);
    Free(us);
  }

  initialised = 0;
}
Exemple #4
0
void
NSR_GetActivityReport(RPT_ActivityReport *report)
{
  SourceRecord *record;
  unsigned int i;
  struct UnresolvedSource *us;

  report->online = 0;
  report->offline = 0;
  report->burst_online = 0;
  report->burst_offline = 0;

  for (i = 0; i < ARR_GetSize(records); i++) {
    record = get_record(i);
    if (record->remote_addr) {
      NCR_IncrementActivityCounters(record->data, &report->online, &report->offline,
                                    &report->burst_online, &report->burst_offline);
    }
  }

  report->unresolved = 0;

  for (us = unresolved_sources; us; us = us->next) {
    report->unresolved++;
  }
}
Exemple #5
0
void NSR_StartSources(void)
{
  unsigned int i;

  for (i = 0; i < ARR_GetSize(records); i++) {
    if (!get_record(i)->remote_addr)
      continue;
    NCR_StartInstance(get_record(i)->data);
  }
}
Exemple #6
0
void
NSR_RefreshAddresses(void)
{
  SourceRecord *record;
  unsigned int i;

  for (i = 0; i < ARR_GetSize(records); i++) {
    record = get_record(i);
    if (!record->remote_addr || !record->name)
      continue;

    resolve_source_replacement(record);
  }
}
Exemple #7
0
void
NSR_RemoveAllSources(void)
{
  SourceRecord *record;
  unsigned int i;

  for (i = 0; i < ARR_GetSize(records); i++) {
    record = get_record(i);
    if (!record->remote_addr)
      continue;
    clean_source_record(record);
  }

  rehash_records();
}
Exemple #8
0
int
NSR_TakeSourcesOffline(IPAddr *mask, IPAddr *address)
{
  SourceRecord *record, *syncpeer;
  unsigned int i, any;

  any = 0;
  syncpeer = NULL;
  for (i = 0; i < ARR_GetSize(records); i++) {
    record = get_record(i);
    if (record->remote_addr) {
      if (address->family == IPADDR_UNSPEC ||
          !UTI_CompareIPs(&record->remote_addr->ip_addr, address, mask)) {
        any = 1;
        if (NCR_IsSyncPeer(record->data)) {
          syncpeer = record;
          continue;
        }
        NCR_TakeSourceOffline(record->data);
      }
    }
  }

  /* Take sync peer offline as last to avoid reference switching */
  if (syncpeer) {
    NCR_TakeSourceOffline(syncpeer->data);
  }

  if (address->family == IPADDR_UNSPEC) {
    struct UnresolvedSource *us;

    for (us = unresolved_sources; us; us = us->next) {
      if (us->replacement)
        continue;
      any = 1;
      us->new_source.params.online = 0;
    }
  }

  return any;
}
Exemple #9
0
static void remove_tentative_pool_sources(int pool)
{
  SourceRecord *record;
  unsigned int i, removed;

  for (i = removed = 0; i < ARR_GetSize(records); i++) {
    record = get_record(i);

    if (!record->remote_addr || record->pool != pool || !record->tentative)
      continue;

    DEBUG_LOG(LOGF_NtpSources, "removing tentative source %s",
              UTI_IPToString(&record->remote_addr->ip_addr));

    clean_source_record(record);
    removed++;
  }

  if (removed)
    rehash_records();
}
Exemple #10
0
static void
slew_sources(struct timeval *raw,
             struct timeval *cooked,
             double dfreq,
             double doffset,
             LCL_ChangeType change_type,
             void *anything)
{
  SourceRecord *record;
  unsigned int i;

  for (i = 0; i < ARR_GetSize(records); i++) {
    record = get_record(i);
    if (record->remote_addr) {
      if (change_type == LCL_ChangeUnknownStep) {
        NCR_ResetInstance(record->data);
      } else {
        NCR_SlewTimes(record->data, cooked, dfreq, doffset);
      }
    }
  }
}
Exemple #11
0
/* Procedure to add a new source */
static NSR_Status
add_source(NTP_Remote_Address *remote_addr, char *name, NTP_Source_Type type, SourceParameters *params, int pool)
{
  SourceRecord *record;
  int slot, found;

  assert(initialised);

  /* Find empty bin & check that we don't have the address already */
  find_slot(remote_addr, &slot, &found);
  if (found) {
    return NSR_AlreadyInUse;
  } else {
    if (remote_addr->ip_addr.family != IPADDR_INET4 &&
               remote_addr->ip_addr.family != IPADDR_INET6) {
      return NSR_InvalidAF;
    } else {
      n_sources++;

      if (!check_hashtable_size(n_sources, ARR_GetSize(records))) {
        rehash_records();
        find_slot(remote_addr, &slot, &found);
      }

      assert(!found);
      record = get_record(slot);
      record->data = NCR_GetInstance(remote_addr, type, params);
      record->remote_addr = NCR_GetRemoteAddress(record->data);
      record->name = name ? Strdup(name) : NULL;
      record->pool = pool;
      record->tentative = 1;

      if (auto_start_sources)
        NCR_StartInstance(record->data);

      return NSR_Success;
    }
  }
}
Exemple #12
0
int
NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples,
                        IPAddr *mask, IPAddr *address)
{
  SourceRecord *record;
  unsigned int i;
  int any;

  any = 0;
  for (i = 0; i < ARR_GetSize(records); i++) {
    record = get_record(i);
    if (record->remote_addr) {
      if (address->family == IPADDR_UNSPEC ||
          !UTI_CompareIPs(&record->remote_addr->ip_addr, address, mask)) {
        any = 1;
        NCR_InitiateSampleBurst(record->data, n_good_samples, n_total_samples);
      }
    }
  }

  return any;

}
Exemple #13
0
void
NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type, SourceParameters *params)
{
  struct UnresolvedSource *us;
  struct SourcePool *sp;
  NTP_Remote_Address remote_addr;

  /* If the name is an IP address, don't bother with full resolving now
     or later when trying to replace the source */
  if (UTI_StringToIP(name, &remote_addr.ip_addr)) {
    remote_addr.port = port;
    NSR_AddSource(&remote_addr, type, params);
    return;
  }

  us = MallocNew(struct UnresolvedSource);
  us->name = Strdup(name);
  us->port = port;
  us->random_order = 0;
  us->replacement = 0;
  us->new_source.type = type;
  us->new_source.params = *params;

  if (!pool) {
    us->new_source.pool = INVALID_POOL;
    us->new_source.max_new_sources = 1;
  } else {
    sp = (struct SourcePool *)ARR_GetNewElement(pools);
    sp->sources = 0;
    sp->max_sources = params->max_sources;
    us->new_source.pool = ARR_GetSize(pools) - 1;
    us->new_source.max_new_sources = MAX_POOL_SOURCES;
  }

  append_unresolved_source(us);
}
Exemple #14
0
static void
find_slot(NTP_Remote_Address *remote_addr, int *slot, int *found)
{
  SourceRecord *record;
  uint32_t hash;
  unsigned int i, size;
  unsigned short port;

  size = ARR_GetSize(records);
  
  if (remote_addr->ip_addr.family != IPADDR_INET4 &&
      remote_addr->ip_addr.family != IPADDR_INET6) {
    *found = *slot = 0;
    return;
  }

  hash = UTI_IPToHash(&remote_addr->ip_addr);
  port = remote_addr->port;

  for (i = 0; i < size / 2; i++) {
    /* Use quadratic probing */
    *slot = (hash + (i + i * i) / 2) % size;
    record = get_record(*slot);

    if (!record->remote_addr)
      break;

    if (!UTI_CompareIPs(&record->remote_addr->ip_addr,
                        &remote_addr->ip_addr, NULL)) {
      *found = record->remote_addr->port == port ? 2 : 1;
      return;
    }
  }

  *found = 0;
}
Exemple #15
0
void
test_unit(void)
{
  int i, j, index;
  struct timespec ts;
  IPAddr ip;
  char conf[][100] = {
    "clientloglimit 10000",
    "ratelimit interval 3 burst 4 leak 3",
    "cmdratelimit interval 3 burst 4 leak 3",
  };

  CNF_Initialise(0, 0);
  for (i = 0; i < sizeof conf / sizeof conf[0]; i++)
    CNF_ParseLine(NULL, i + 1, conf[i]);

  CLG_Initialise();

  TEST_CHECK(ARR_GetSize(records) == 16);

  for (i = 0; i < 500; i++) {
    DEBUG_LOG("iteration %d", i);

    ts.tv_sec = (time_t)random() & 0x0fffffff;
    ts.tv_nsec = 0;

    for (j = 0; j < 1000; j++) {
      TST_GetRandomAddress(&ip, IPADDR_UNSPEC, i % 8 ? -1 : i / 8 % 9);
      DEBUG_LOG("address %s", UTI_IPToString(&ip));

      if (random() % 2) {
        index = CLG_LogNTPAccess(&ip, &ts);
        TEST_CHECK(index >= 0);
        CLG_LimitNTPResponseRate(index);
      } else {
        index = CLG_LogCommandAccess(&ip, &ts);
        TEST_CHECK(index >= 0);
        CLG_LimitCommandResponseRate(index);
      }

      UTI_AddDoubleToTimespec(&ts, (1 << random() % 14) / 100.0, &ts);
    }
  }

  DEBUG_LOG("records %u", ARR_GetSize(records));
  TEST_CHECK(ARR_GetSize(records) == 64);

  for (i = j = 0; i < 10000; i++) {
    ts.tv_sec += 1;
    index = CLG_LogNTPAccess(&ip, &ts);
    TEST_CHECK(index >= 0);
    if (!CLG_LimitNTPResponseRate(index))
      j++;
  }

  DEBUG_LOG("requests %d responses %d", i, j);
  TEST_CHECK(j * 4 < i && j * 6 > i);

  CLG_Finalise();
  CNF_Finalise();
}