コード例 #1
0
ファイル: ntp_sources.c プロジェクト: pompomJuice/chrony
static void
process_resolved_name(struct UnresolvedSource *us, IPAddr *ip_addrs, int n_addrs)
{
  NTP_Remote_Address address;
  int i, added;
  unsigned short first = 0;

  if (us->random_order)
    UTI_GetRandomBytes(&first, sizeof (first));

  for (i = added = 0; i < n_addrs; i++) {
    address.ip_addr = ip_addrs[((unsigned int)i + first) % n_addrs];
    address.port = us->port;

    DEBUG_LOG(LOGF_NtpSources, "(%d) %s", i + 1, UTI_IPToString(&address.ip_addr));

    if (us->replacement) {
      if (replace_source(&us->replace_source, &address) != NSR_AlreadyInUse)
        break;
    } else {
      if (add_source(&address, us->name, us->new_source.type, &us->new_source.params,
                     us->new_source.pool) == NSR_Success)
        added++;

      if (added >= us->new_source.max_new_sources)
        break;
    }
  }
}
コード例 #2
0
ファイル: nameserv.c プロジェクト: rbrito/pkg-chrony
int
DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len)
{
  char *result = NULL;

#ifdef HAVE_IPV6
  struct sockaddr_in in4;
  struct sockaddr_in6 in6;
  char hbuf[NI_MAXHOST];

  switch (ip_addr->family) {
    case IPADDR_INET4:
      memset(&in4, 0, sizeof (in4));
#ifdef SIN6_LEN
      in4.sin_len = sizeof (in4);
#endif
      in4.sin_family = AF_INET;
      in4.sin_addr.s_addr = htonl(ip_addr->addr.in4);
      if (!getnameinfo((const struct sockaddr *)&in4, sizeof (in4), hbuf, sizeof (hbuf), NULL, 0, 0))
        result = hbuf;
      break;
    case IPADDR_INET6:
      memset(&in6, 0, sizeof (in6));
#ifdef SIN6_LEN
      in6.sin6_len = sizeof (in6);
#endif
      in6.sin6_family = AF_INET6;
      memcpy(&in6.sin6_addr.s6_addr, ip_addr->addr.in6, sizeof (in6.sin6_addr.s6_addr));
      if (!getnameinfo((const struct sockaddr *)&in6, sizeof (in6), hbuf, sizeof (hbuf), NULL, 0, 0))
        result = hbuf;
      break;
  }
#else
  struct hostent *host;
  uint32_t addr;

  switch (ip_addr->family) {
    case IPADDR_INET4:
      addr = htonl(ip_addr->addr.in4);
      host = gethostbyaddr((const char *) &addr, sizeof (ip_addr), AF_INET);
      break;
#ifdef HAVE_IPV6
    case IPADDR_INET6:
      host = gethostbyaddr((const void *) ip_addr->addr.in6, sizeof (ip_addr->addr.in6), AF_INET6);
      break;
#endif
    default:
      host = NULL;
  }
  if (host)
    result = host->h_name;
#endif

  if (result == NULL)
    result = UTI_IPToString(ip_addr);
  if (snprintf(name, len, "%s", result) >= len)
    return 0;

  return 1;
}
コード例 #3
0
ファイル: ntp_sources.c プロジェクト: pompomJuice/chrony
static NSR_Status
replace_source(NTP_Remote_Address *old_addr, NTP_Remote_Address *new_addr)
{
  int slot1, slot2, found;
  SourceRecord *record;
  struct SourcePool *pool;

  find_slot(old_addr, &slot1, &found);
  if (!found)
    return NSR_NoSuchSource;

  find_slot(new_addr, &slot2, &found);
  if (found)
    return NSR_AlreadyInUse;

  record = get_record(slot1);
  NCR_ChangeRemoteAddress(record->data, new_addr);
  record->remote_addr = NCR_GetRemoteAddress(record->data);

  if (!record->tentative) {
    record->tentative = 1;

    if (record->pool != INVALID_POOL) {
      pool = ARR_GetElement(pools, record->pool);
      pool->sources--;
    }
  }

  /* The hash table must be rebuilt for the new address */
  rehash_records();

  LOG(LOGS_INFO, LOGF_NtpSources, "Source %s replaced with %s",
      UTI_IPToString(&old_addr->ip_addr),
      UTI_IPToString(&new_addr->ip_addr));

  return NSR_Success;
}
コード例 #4
0
ファイル: nameserv.c プロジェクト: SuperQ/chrony
int
DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len)
{
  char *result = NULL;

#ifdef FEAT_IPV6
  struct sockaddr_in6 in6;
  socklen_t slen;
  char hbuf[NI_MAXHOST];

  slen = UTI_IPAndPortToSockaddr(ip_addr, 0, (struct sockaddr *)&in6);
  if (!getnameinfo((struct sockaddr *)&in6, slen, hbuf, sizeof (hbuf), NULL, 0, 0))
    result = hbuf;
#else
  struct hostent *host;
  uint32_t addr;

  switch (ip_addr->family) {
    case IPADDR_INET4:
      addr = htonl(ip_addr->addr.in4);
      host = gethostbyaddr((const char *) &addr, sizeof (ip_addr), AF_INET);
      break;
#ifdef FEAT_IPV6
    case IPADDR_INET6:
      host = gethostbyaddr((const void *) ip_addr->addr.in6, sizeof (ip_addr->addr.in6), AF_INET6);
      break;
#endif
    default:
      host = NULL;
  }
  if (host)
    result = host->h_name;
#endif

  if (result == NULL)
    result = UTI_IPToString(ip_addr);
  if (snprintf(name, len, "%s", result) >= len)
    return 0;

  return 1;
}
コード例 #5
0
ファイル: sourcestats.c プロジェクト: vulpicastor/chrony
void
SST_AccumulateSample(SST_Stats inst, struct timeval *sample_time,
                     double offset,
                     double peer_delay, double peer_dispersion,
                     double root_delay, double root_dispersion,
                     int stratum)
{
  int n, m;

  /* Make room for the new sample */
  if (inst->n_samples > 0 &&
      (inst->n_samples == MAX_SAMPLES || inst->n_samples == max_samples)) {
    prune_register(inst, 1);
  }

  /* Make sure it's newer than the last sample */
  if (inst->n_samples &&
      UTI_CompareTimevals(&inst->sample_times[inst->last_sample], sample_time) >= 0) {
    LOG(LOGS_WARN, LOGF_SourceStats, "Out of order sample detected, discarding history for %s",
        inst->ip_addr ? UTI_IPToString(inst->ip_addr) : UTI_RefidToString(inst->refid));
    SST_ResetInstance(inst);
  }

  n = inst->last_sample = (inst->last_sample + 1) %
    (MAX_SAMPLES * REGRESS_RUNS_RATIO);
  m = n % MAX_SAMPLES;

  inst->sample_times[n] = *sample_time;
  inst->offsets[n] = offset;
  inst->orig_offsets[m] = offset;
  inst->peer_delays[m] = peer_delay;
  inst->peer_dispersions[m] = peer_dispersion;
  inst->root_delays[m] = root_delay;
  inst->root_dispersions[m] = root_dispersion;
  inst->strata[m] = stratum;
 
  if (!inst->n_samples || inst->peer_delays[m] < inst->peer_delays[inst->min_delay_sample])
    inst->min_delay_sample = m;

  ++inst->n_samples;
}
コード例 #6
0
ファイル: ntp_sources.c プロジェクト: pompomJuice/chrony
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();
}
コード例 #7
0
ファイル: ntp_sources.c プロジェクト: pompomJuice/chrony
static void
resolve_source_replacement(SourceRecord *record)
{
  struct UnresolvedSource *us;

  DEBUG_LOG(LOGF_NtpSources, "trying to replace %s",
            UTI_IPToString(&record->remote_addr->ip_addr));

  us = MallocNew(struct UnresolvedSource);
  us->name = Strdup(record->name);
  us->port = record->remote_addr->port;
  /* If there never was a valid reply from this source (e.g. it was a bad
     replacement), ignore the order of addresses from the resolver to not get
     stuck to a pair of addresses if the order doesn't change, or a group of
     IPv4/IPv6 addresses if the resolver prefers inaccessible IP family */
  us->random_order = record->tentative;
  us->replacement = 1;
  us->replace_source = *record->remote_addr;

  append_unresolved_source(us);
  NSR_ResolveSources();
}
コード例 #8
0
ファイル: clientlog.c プロジェクト: mlichvar/chrony
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();
}
コード例 #9
0
ファイル: sourcestats.c プロジェクト: vulpicastor/chrony
void
SST_DoNewRegression(SST_Stats inst)
{
  double times_back[MAX_SAMPLES * REGRESS_RUNS_RATIO];
  double offsets[MAX_SAMPLES * REGRESS_RUNS_RATIO];
  double peer_distances[MAX_SAMPLES];
  double weights[MAX_SAMPLES];

  int degrees_of_freedom;
  int best_start, times_back_start;
  double est_intercept, est_slope, est_var, est_intercept_sd, est_slope_sd;
  int i, j, nruns;
  double min_distance, mean_distance;
  double sd_weight, sd;
  double old_skew, old_freq, stress;

  convert_to_intervals(inst, times_back + inst->runs_samples);

  if (inst->n_samples > 0) {
    for (i = -inst->runs_samples; i < inst->n_samples; i++) {
      offsets[i + inst->runs_samples] = inst->offsets[get_runsbuf_index(inst, i)];
    }
  
    for (i = 0, mean_distance = 0.0, min_distance = DBL_MAX; i < inst->n_samples; i++) {
      j = get_buf_index(inst, i);
      peer_distances[i] = 0.5 * inst->peer_delays[j] + inst->peer_dispersions[j];
      mean_distance += peer_distances[i];
      if (peer_distances[i] < min_distance) {
        min_distance = peer_distances[i];
      }
    }
    mean_distance /= inst->n_samples;

    /* And now, work out the weight vector */

    sd = mean_distance - min_distance;
    if (sd > min_distance || sd <= 0.0)
      sd = min_distance;

    for (i=0; i<inst->n_samples; i++) {
      sd_weight = 1.0 + SD_TO_DIST_RATIO * (peer_distances[i] - min_distance) / sd;
      weights[i] = sd_weight * sd_weight;
    }
  }

  inst->regression_ok = RGR_FindBestRegression(times_back + inst->runs_samples,
                                         offsets + inst->runs_samples, weights,
                                         inst->n_samples, inst->runs_samples,
                                         min_samples,
                                         &est_intercept, &est_slope, &est_var,
                                         &est_intercept_sd, &est_slope_sd,
                                         &best_start, &nruns, &degrees_of_freedom);

  if (inst->regression_ok) {

    old_skew = inst->skew;
    old_freq = inst->estimated_frequency;
  
    inst->estimated_frequency = est_slope;
    inst->skew = est_slope_sd * RGR_GetTCoef(degrees_of_freedom);
    inst->estimated_offset = est_intercept;
    inst->offset_time = inst->sample_times[inst->last_sample];
    inst->estimated_offset_sd = est_intercept_sd;
    inst->variance = est_var;
    inst->nruns = nruns;

    if (inst->skew < MIN_SKEW)
      inst->skew = MIN_SKEW;

    stress = fabs(old_freq - inst->estimated_frequency) / old_skew;

    if (best_start > 0) {
      /* If we are throwing old data away, retain the current
         assumptions about the skew */
      inst->skew_dirn = SST_Skew_Nochange;
    } else {
      if (inst->skew < old_skew) {
        inst->skew_dirn = SST_Skew_Decrease;
      } else {
        inst->skew_dirn = SST_Skew_Increase;
      }
    }

    if (logfileid != -1) {
      LOG_FileWrite(logfileid, "%s %-15s %10.3e %10.3e %10.3e %10.3e %10.3e %7.1e %3d %3d %3d",
              UTI_TimeToLogForm(inst->offset_time.tv_sec),
              inst->ip_addr ? UTI_IPToString(inst->ip_addr) : UTI_RefidToString(inst->refid),
              sqrt(inst->variance),
              inst->estimated_offset,
              inst->estimated_offset_sd,
              inst->estimated_frequency,
              inst->skew,
              stress,
              inst->n_samples,
              best_start, nruns);
    }

    times_back_start = inst->runs_samples + best_start;
    prune_register(inst, best_start);
  } else {
    inst->estimated_frequency = 0.0;
    inst->skew = WORST_CASE_FREQ_BOUND;
    times_back_start = 0;
  }

  find_best_sample_index(inst, times_back + times_back_start);

}