Make receive_packet() more readable

This commit is contained in:
Miroslav Lichvar 2013-06-03 14:27:09 +02:00
parent 5079f6bbff
commit 030e3b2dab

View file

@ -389,6 +389,39 @@ adjust_poll(NCR_Instance inst, double adj)
/* ================================================== */
static double
get_poll_adj(NCR_Instance inst, double error_in_estimate, double peer_distance)
{
double poll_adj;
if (error_in_estimate > peer_distance) {
int shift = 0;
unsigned long temp = (int)(error_in_estimate / peer_distance);
do {
shift++;
temp>>=1;
} while (temp);
poll_adj = -shift - inst->poll_score + 0.5;
} else {
int samples = SRC_Samples(inst->source);
/* Adjust polling interval so that the number of sourcestats samples
remains close to the target value */
poll_adj = ((double)samples / inst->poll_target - 1.0) / inst->poll_target;
/* Make interval shortening quicker */
if (samples < inst->poll_target) {
poll_adj *= 2.0;
}
}
return poll_adj;
}
/* ================================================== */
static void
transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
int my_poll, /* The log2 of the local poll interval */
@ -716,7 +749,6 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
int poll_to_use;
double delay_time = 0;
int requeue_transmit = 0;
double poll_adj;
/* ==================== */
@ -935,7 +967,7 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
}
/* Check for Kiss-of-Death */
if (message->stratum > NTP_MAX_STRATUM && !source_is_synchronized) {
if (!test7i && !source_is_synchronized) {
if (!memcmp(&message->reference_id, "RATE", 4))
kod_rate = 1;
}
@ -982,6 +1014,26 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
LOG(LOGS_INFO, LOGF_NtpCore, "kod_rate=%d valid_kod=%d", kod_rate, valid_kod);
#endif
/* Reduce polling rate if KoD RATE was received */
if (kod_rate && valid_kod) {
if (inst->remote_poll > inst->minpoll) {
inst->minpoll = inst->remote_poll;
if (inst->minpoll > inst->maxpoll)
inst->maxpoll = inst->minpoll;
if (inst->minpoll > inst->local_poll)
inst->local_poll = inst->minpoll;
LOG(LOGS_WARN, LOGF_NtpCore, "Received KoD RATE from %s, minpoll set to %d",
UTI_IPToString(&inst->remote_addr.ip_addr), inst->minpoll);
}
/* Stop ongoing burst */
if (inst->opmode == MD_BURST_WAS_OFFLINE || inst->opmode == MD_BURST_WAS_ONLINE) {
inst->burst_good_samples_to_go = 0;
LOG(LOGS_WARN, LOGF_NtpCore, "Received KoD RATE from %s, burst sampling stopped",
UTI_IPToString(&inst->remote_addr.ip_addr), inst->minpoll);
}
}
if (valid_header && valid_data) {
inst->tx_count = 0;
SRC_UpdateReachability(inst->source, 1);
@ -996,12 +1048,11 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
} else {
SRC_UnsetSelectable(inst->source);
}
}
if (good_data) {
/* Do this before we accumulate a new sample into the stats registers, obviously */
estimated_offset = SRC_PredictOffset(inst->source, &sample_time);
if (valid_header && good_data) {
SRC_AccumulateSample(inst->source,
&sample_time,
theta, delta, epsilon,
@ -1013,87 +1064,37 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
not tracking the peer at all well, so we back off the sampling
rate depending on just how bad the situation is. */
error_in_estimate = fabs(-theta - estimated_offset);
/* Now update the polling interval */
if (error_in_estimate > peer_distance) {
int shift = 0;
unsigned long temp = (int)(error_in_estimate / peer_distance);
do {
shift++;
temp>>=1;
} while (temp);
poll_adj = -shift - inst->poll_score + 0.5;
} else {
int samples = SRC_Samples(inst->source);
/* Adjust polling interval so that the number of sourcestats samples
remains close to the target value */
poll_adj = ((double)samples / inst->poll_target - 1.0) / inst->poll_target;
/* Use higher gain when decreasing the interval */
if (samples < inst->poll_target) {
poll_adj *= 2.0;
}
}
adjust_poll(inst, poll_adj);
} else if (valid_header && valid_data) {
/* Slowly increase the polling interval if we can't get good_data */
adjust_poll(inst, 0.1);
}
/* Reduce polling rate if KoD RATE was received */
if (kod_rate && valid_kod) {
if (inst->remote_poll > inst->minpoll) {
inst->minpoll = inst->remote_poll;
if (inst->minpoll > inst->maxpoll)
inst->maxpoll = inst->minpoll;
if (inst->minpoll > inst->local_poll)
inst->local_poll = inst->minpoll;
LOG(LOGS_WARN, LOGF_NtpCore, "Received KoD RATE from %s, minpoll set to %d", UTI_IPToString(&inst->remote_addr.ip_addr), inst->minpoll);
}
/* Stop ongoing burst */
if (inst->opmode == MD_BURST_WAS_OFFLINE || inst->opmode == MD_BURST_WAS_ONLINE) {
inst->burst_good_samples_to_go = 0;
LOG(LOGS_WARN, LOGF_NtpCore, "Received KoD RATE from %s, burst sampling stopped", UTI_IPToString(&inst->remote_addr.ip_addr), inst->minpoll);
}
}
adjust_poll(inst, get_poll_adj(inst, error_in_estimate, peer_distance));
/* If we're in burst mode, check whether the burst is completed and
revert to the previous mode */
switch (inst->opmode) {
case MD_BURST_WAS_ONLINE:
if (valid_header && good_data) {
--inst->burst_good_samples_to_go;
}
if (inst->burst_good_samples_to_go <= 0) {
inst->opmode = MD_ONLINE;
}
break;
case MD_BURST_WAS_OFFLINE:
if (valid_header && good_data) {
--inst->burst_good_samples_to_go;
}
if (inst->burst_good_samples_to_go <= 0) {
if (inst->opmode == MD_BURST_WAS_ONLINE) {
inst->opmode = MD_ONLINE;
} else {
inst->opmode = MD_OFFLINE;
if (inst->timer_running) {
SCH_RemoveTimeout(inst->timeout_id);
}
inst->timer_running = 0;
}
}
}
break;
default:
break;
}
} else {
/* Slowly increase the polling interval if we can't get good_data */
adjust_poll(inst, 0.1);
}
}
/* And now, requeue the timer.
@ -1151,12 +1152,10 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
assert(0);
break;
}
break;
case MD_BURST_WAS_ONLINE:
case MD_BURST_WAS_OFFLINE:
requeue_transmit = 1;
delay_time = BURST_INTERVAL;
break;
@ -1164,7 +1163,6 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
default:
assert(0);
break;
}
if (kod_rate && valid_kod) {
@ -1174,6 +1172,7 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
if (requeue_transmit) {
/* Get rid of old timeout and start a new one */
assert(inst->timer_running);
SCH_RemoveTimeout(inst->timeout_id);
inst->timeout_id = SCH_AddTimeoutInClass(delay_time, SAMPLING_SEPARATION,
SAMPLING_RANDOMNESS,
@ -1196,12 +1195,6 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
theta, delta, epsilon,
pkt_root_delay, pkt_root_dispersion);
}
/* At this point we will have to do something about trimming the
poll interval for the source and requeueing the polling timeout.
Left until the source statistics management has been written */
}
/* ================================================== */