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; } } }
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; }
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; }
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; }
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; }
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(); }
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(); }
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(); }
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, °rees_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); }