ntpd: preparatory patches, no functional changes

function                                             old     new   delta
ntp_init                                             354     357      +3
ntpd_main                                           2945    2898     -47

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2009-12-30 18:38:05 +01:00
parent bd1de181ad
commit d2fe69f9dc

View File

@ -29,7 +29,7 @@
#define QSCALE_OFF_MIN 0.05 #define QSCALE_OFF_MIN 0.05
#define QSCALE_OFF_MAX 0.50 #define QSCALE_OFF_MAX 0.50
/* Single query might take n secs max */ /* Single query might take N secs max */
#define QUERYTIME_MAX 15 #define QUERYTIME_MAX 15
/* Min offset for settime at start. "man ntpd" says it's 128 ms */ /* Min offset for settime at start. "man ntpd" says it's 128 ms */
#define STEPTIME_MIN_OFFSET 0.128 #define STEPTIME_MIN_OFFSET 0.128
@ -54,7 +54,7 @@ typedef struct {
uint8_t m_status; /* status of local clock and leap info */ uint8_t m_status; /* status of local clock and leap info */
uint8_t m_stratum; /* stratum level */ uint8_t m_stratum; /* stratum level */
uint8_t m_ppoll; /* poll value */ uint8_t m_ppoll; /* poll value */
int8_t m_precision; int8_t m_precision_exp;
s_fixedpt_t m_rootdelay; s_fixedpt_t m_rootdelay;
s_fixedpt_t m_dispersion; s_fixedpt_t m_dispersion;
uint32_t m_refid; uint32_t m_refid;
@ -64,16 +64,11 @@ typedef struct {
l_fixedpt_t m_xmttime; l_fixedpt_t m_xmttime;
uint32_t m_keyid; uint32_t m_keyid;
uint8_t m_digest[NTP_DIGESTSIZE]; uint8_t m_digest[NTP_DIGESTSIZE];
} ntp_msg_t; } msg_t;
enum { enum {
NTP_VERSION = 4, NTP_VERSION = 4,
NTP_MAXSTRATUM = 15, NTP_MAXSTRATUM = 15,
/* Leap Second Codes (high order two bits of m_status) */
LI_NOWARNING = (0 << 6), /* no warning */
LI_PLUSSEC = (1 << 6), /* add a second (61 seconds) */
LI_MINUSSEC = (2 << 6), /* minus a second (59 seconds) */
LI_ALARM = (3 << 6), /* alarm condition */
/* Status Masks */ /* Status Masks */
MODE_MASK = (7 << 0), MODE_MASK = (7 << 0),
@ -81,6 +76,12 @@ enum {
VERSION_SHIFT = 3, VERSION_SHIFT = 3,
LI_MASK = (3 << 6), LI_MASK = (3 << 6),
/* Leap Second Codes (high order two bits of m_status) */
LI_NOWARNING = (0 << 6), /* no warning */
LI_PLUSSEC = (1 << 6), /* add a second (61 seconds) */
LI_MINUSSEC = (2 << 6), /* minus a second (59 seconds) */
LI_ALARM = (3 << 6), /* alarm condition */
/* Mode values */ /* Mode values */
MODE_RES0 = 0, /* reserved */ MODE_RES0 = 0, /* reserved */
MODE_SYM_ACT = 1, /* symmetric active */ MODE_SYM_ACT = 1, /* symmetric active */
@ -103,7 +104,7 @@ typedef struct {
uint8_t d_leap; uint8_t d_leap;
uint8_t d_stratum; uint8_t d_stratum;
uint8_t d_good; uint8_t d_good;
} ntp_datapoint_t; } datapoint_t;
#define NUM_DATAPOINTS 8 #define NUM_DATAPOINTS 8
typedef struct { typedef struct {
@ -114,12 +115,12 @@ typedef struct {
time_t next_action_time; time_t next_action_time;
int p_fd; int p_fd;
uint8_t p_datapoint_idx; uint8_t p_datapoint_idx;
uint8_t trustlevel; uint8_t p_trustlevel;
ntp_msg_t msg;
double p_xmttime; double p_xmttime;
ntp_datapoint_t update; datapoint_t update;
ntp_datapoint_t p_datapoint[NUM_DATAPOINTS]; datapoint_t p_datapoint[NUM_DATAPOINTS];
} ntp_peer_t; msg_t p_xmt_msg;
} peer_t;
enum { enum {
OPT_n = (1 << 0), OPT_n = (1 << 0),
@ -134,7 +135,9 @@ enum {
struct globals { struct globals {
/* total round trip delay to currently selected reference clock */
double rootdelay; double rootdelay;
/* reference timestamp: time when the system clock was last set or corrected */
double reftime; double reftime;
llist_t *ntp_peers; llist_t *ntp_peers;
#if ENABLE_FEATURE_NTPD_SERVER #if ENABLE_FEATURE_NTPD_SERVER
@ -155,12 +158,11 @@ struct globals {
}; };
#define G (*ptr_to_globals) #define G (*ptr_to_globals)
static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY; static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY;
static void static void
set_next(ntp_peer_t *p, unsigned t) set_next(peer_t *p, unsigned t)
{ {
p->next_action_time = time(NULL) + t; p->next_action_time = time(NULL) + t;
} }
@ -168,14 +170,14 @@ set_next(ntp_peer_t *p, unsigned t)
static void static void
add_peers(char *s) add_peers(char *s)
{ {
ntp_peer_t *p; peer_t *p;
p = xzalloc(sizeof(*p)); p = xzalloc(sizeof(*p));
p->p_lsa = xhost2sockaddr(s, 123); p->p_lsa = xhost2sockaddr(s, 123);
p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa);
p->p_fd = -1; p->p_fd = -1;
p->msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3);
p->trustlevel = TRUSTLEVEL_PATHETIC; p->p_trustlevel = TRUSTLEVEL_PATHETIC;
p->next_action_time = time(NULL); /* = set_next(p, 0); */ p->next_action_time = time(NULL); /* = set_next(p, 0); */
llist_add_to(&G.ntp_peers, p); llist_add_to(&G.ntp_peers, p);
@ -255,7 +257,7 @@ error_interval(void)
static int static int
do_sendto(int fd, do_sendto(int fd,
const struct sockaddr *from, const struct sockaddr *to, socklen_t addrlen, const struct sockaddr *from, const struct sockaddr *to, socklen_t addrlen,
ntp_msg_t *msg, ssize_t len) msg_t *msg, ssize_t len)
{ {
ssize_t ret; ssize_t ret;
@ -273,7 +275,7 @@ do_sendto(int fd,
} }
static int static int
send_query_to_peer(ntp_peer_t *p) send_query_to_peer(peer_t *p)
{ {
// Why do we need to bind()? // Why do we need to bind()?
// See what happens when we don't bind: // See what happens when we don't bind:
@ -326,12 +328,12 @@ send_query_to_peer(ntp_peer_t *p)
* *
* Save the real transmit timestamp locally. * Save the real transmit timestamp locally.
*/ */
p->msg.m_xmttime.int_partl = random(); p->p_xmt_msg.m_xmttime.int_partl = random();
p->msg.m_xmttime.fractionl = random(); p->p_xmt_msg.m_xmttime.fractionl = random();
p->p_xmttime = gettime1900d(); p->p_xmttime = gettime1900d();
if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len, if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len,
&p->msg, NTP_MSGSIZE_NOAUTH) == -1 &p->p_xmt_msg, NTP_MSGSIZE_NOAUTH) == -1
) { ) {
close(p->p_fd); close(p->p_fd);
p->p_fd = -1; p->p_fd = -1;
@ -380,7 +382,7 @@ step_time_once(double offset)
bb_error_msg("setting clock to %s (offset %fs)", buf, offset); bb_error_msg("setting clock to %s (offset %fs)", buf, offset);
for (item = G.ntp_peers; item != NULL; item = item->link) { for (item = G.ntp_peers; item != NULL; item = item->link) {
ntp_peer_t *p = (ntp_peer_t *) item->data; peer_t *p = (peer_t *) item->data;
p->next_action_time -= (time_t)offset; p->next_action_time -= (time_t)offset;
} }
@ -396,8 +398,8 @@ step_time_once(double offset)
static int static int
compare_offsets(const void *aa, const void *bb) compare_offsets(const void *aa, const void *bb)
{ {
const ntp_peer_t *const *a = aa; const peer_t *const *a = aa;
const ntp_peer_t *const *b = bb; const peer_t *const *b = bb;
if ((*a)->update.d_offset < (*b)->update.d_offset) if ((*a)->update.d_offset < (*b)->update.d_offset)
return -1; return -1;
return ((*a)->update.d_offset > (*b)->update.d_offset); return ((*a)->update.d_offset > (*b)->update.d_offset);
@ -421,13 +423,13 @@ slew_time(void)
struct timeval tv; struct timeval tv;
{ {
ntp_peer_t **peers = xzalloc(sizeof(peers[0]) * G.peer_cnt); peer_t **peers = xzalloc(sizeof(peers[0]) * G.peer_cnt);
unsigned goodpeer_cnt = 0; unsigned goodpeer_cnt = 0;
unsigned middle; unsigned middle;
for (item = G.ntp_peers; item != NULL; item = item->link) { for (item = G.ntp_peers; item != NULL; item = item->link) {
ntp_peer_t *p = (ntp_peer_t *) item->data; peer_t *p = (peer_t *) item->data;
if (p->trustlevel < TRUSTLEVEL_BADPEER) if (p->p_trustlevel < TRUSTLEVEL_BADPEER)
continue; continue;
if (!p->update.d_good) { if (!p->update.d_good) {
free(peers); free(peers);
@ -490,13 +492,13 @@ slew_time(void)
clear_good: clear_good:
for (item = G.ntp_peers; item != NULL; item = item->link) { for (item = G.ntp_peers; item != NULL; item = item->link) {
ntp_peer_t *p = (ntp_peer_t *) item->data; peer_t *p = (peer_t *) item->data;
p->update.d_good = 0; p->update.d_good = 0;
} }
} }
static void static void
update_peer_data(ntp_peer_t *p) update_peer_data(peer_t *p)
{ {
/* Clock filter. /* Clock filter.
* Find the datapoint with the lowest delay. * Find the datapoint with the lowest delay.
@ -535,13 +537,13 @@ scale_interval(unsigned requested)
return (interval + r); return (interval + r);
} }
static void static void
recv_and_process_peer_pkt(ntp_peer_t *p) recv_and_process_peer_pkt(peer_t *p)
{ {
ssize_t size; ssize_t size;
ntp_msg_t msg; msg_t msg;
double T1, T2, T3, T4; double T1, T2, T3, T4;
unsigned interval; unsigned interval;
ntp_datapoint_t *datapoint; datapoint_t *datapoint;
/* We can recvfrom here and check from.IP, but some multihomed /* We can recvfrom here and check from.IP, but some multihomed
* ntp servers reply from their *other IP*. * ntp servers reply from their *other IP*.
@ -567,8 +569,8 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
goto bail; goto bail;
} }
if (msg.m_orgtime.int_partl != p->msg.m_xmttime.int_partl if (msg.m_orgtime.int_partl != p->p_xmt_msg.m_xmttime.int_partl
|| msg.m_orgtime.fractionl != p->msg.m_xmttime.fractionl || msg.m_orgtime.fractionl != p->p_xmt_msg.m_xmttime.fractionl
) { ) {
goto bail; goto bail;
} }
@ -599,10 +601,10 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
* *
* delay = (T4 - T1) - (T3 - T2); offset = ((T2 - T1) + (T3 - T4)) / 2 * delay = (T4 - T1) - (T3 - T2); offset = ((T2 - T1) + (T3 - T4)) / 2
*/ */
T4 = gettime1900d();
T1 = p->p_xmttime; T1 = p->p_xmttime;
T2 = lfp_to_d(msg.m_rectime); T2 = lfp_to_d(msg.m_rectime);
T3 = lfp_to_d(msg.m_xmttime); T3 = lfp_to_d(msg.m_xmttime);
T4 = gettime1900d();
datapoint = &p->p_datapoint[p->p_datapoint_idx]; datapoint = &p->p_datapoint[p->p_datapoint_idx];
@ -619,7 +621,7 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
datapoint->d_good = 1; datapoint->d_good = 1;
datapoint->d_leap = (msg.m_status & LI_MASK); datapoint->d_leap = (msg.m_status & LI_MASK);
//UNUSED: datapoint->o_precision = msg.m_precision; //UNUSED: datapoint->o_precision = msg.m_precision_exp;
//UNUSED: datapoint->o_rootdelay = sfp_to_d(msg.m_rootdelay); //UNUSED: datapoint->o_rootdelay = sfp_to_d(msg.m_rootdelay);
//UNUSED: datapoint->o_rootdispersion = sfp_to_d(msg.m_dispersion); //UNUSED: datapoint->o_rootdispersion = sfp_to_d(msg.m_dispersion);
//UNUSED: datapoint->d_refid = ntohl(msg.m_refid); //UNUSED: datapoint->d_refid = ntohl(msg.m_refid);
@ -628,19 +630,19 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
//UNUSED: datapoint->o_poll = msg.m_ppoll; //UNUSED: datapoint->o_poll = msg.m_ppoll;
datapoint->d_stratum = msg.m_stratum; datapoint->d_stratum = msg.m_stratum;
if (p->trustlevel < TRUSTLEVEL_PATHETIC) if (p->p_trustlevel < TRUSTLEVEL_PATHETIC)
interval = scale_interval(INTERVAL_QUERY_PATHETIC); interval = scale_interval(INTERVAL_QUERY_PATHETIC);
else if (p->trustlevel < TRUSTLEVEL_AGRESSIVE) else if (p->p_trustlevel < TRUSTLEVEL_AGRESSIVE)
interval = scale_interval(INTERVAL_QUERY_AGRESSIVE); interval = scale_interval(INTERVAL_QUERY_AGRESSIVE);
else else
interval = scale_interval(INTERVAL_QUERY_NORMAL); interval = scale_interval(INTERVAL_QUERY_NORMAL);
set_next(p, interval); set_next(p, interval);
/* every received reply which we do not discard increases trust */ /* Every received reply which we do not discard increases trust */
if (p->trustlevel < TRUSTLEVEL_MAX) { if (p->p_trustlevel < TRUSTLEVEL_MAX) {
p->trustlevel++; p->p_trustlevel++;
if (p->trustlevel == TRUSTLEVEL_BADPEER) if (p->p_trustlevel == TRUSTLEVEL_BADPEER)
bb_error_msg("peer %s now valid", p->p_dotted); bb_error_msg("peer %s now valid", p->p_dotted);
} }
@ -676,7 +678,7 @@ recv_and_process_client_pkt(void /*int fd*/)
double rectime; double rectime;
len_and_sockaddr *to; len_and_sockaddr *to;
struct sockaddr *from; struct sockaddr *from;
ntp_msg_t msg; msg_t msg;
uint8_t query_status; uint8_t query_status;
uint8_t query_ppoll; uint8_t query_ppoll;
l_fixedpt_t query_xmttime; l_fixedpt_t query_xmttime;
@ -710,7 +712,7 @@ recv_and_process_client_pkt(void /*int fd*/)
MODE_SERVER : MODE_SYM_PAS; MODE_SERVER : MODE_SYM_PAS;
msg.m_stratum = G.stratum; msg.m_stratum = G.stratum;
msg.m_ppoll = query_ppoll; msg.m_ppoll = query_ppoll;
msg.m_precision = G_precision_exp; msg.m_precision_exp = G_precision_exp;
rectime = gettime1900d(); rectime = gettime1900d();
msg.m_xmttime = msg.m_rectime = d_to_lfp(rectime); msg.m_xmttime = msg.m_rectime = d_to_lfp(rectime);
msg.m_reftime = d_to_lfp(G.reftime); msg.m_reftime = d_to_lfp(G.reftime);
@ -894,7 +896,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
{ {
struct globals g; struct globals g;
struct pollfd *pfd; struct pollfd *pfd;
ntp_peer_t **idx2peer; peer_t **idx2peer;
memset(&g, 0, sizeof(g)); memset(&g, 0, sizeof(g));
SET_PTR_TO_GLOBALS(&g); SET_PTR_TO_GLOBALS(&g);
@ -902,10 +904,10 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
ntp_init(argv); ntp_init(argv);
{ {
unsigned cnt = g.peer_cnt;
/* if ENABLE_FEATURE_NTPD_SERVER, + 1 for listen_fd: */ /* if ENABLE_FEATURE_NTPD_SERVER, + 1 for listen_fd: */
idx2peer = xzalloc(sizeof(void *) * (cnt + ENABLE_FEATURE_NTPD_SERVER)); unsigned cnt = g.peer_cnt + ENABLE_FEATURE_NTPD_SERVER;
pfd = xzalloc(sizeof(pfd[0]) * (cnt + ENABLE_FEATURE_NTPD_SERVER)); idx2peer = xzalloc(sizeof(idx2peer[0]) * cnt);
pfd = xzalloc(sizeof(pfd[0]) * cnt);
} }
while (!bb_got_signal) { while (!bb_got_signal) {
@ -931,7 +933,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
/* Pass over peer list, send requests, time out on receives */ /* Pass over peer list, send requests, time out on receives */
sent_cnt = trial_cnt = 0; sent_cnt = trial_cnt = 0;
for (item = g.ntp_peers; item != NULL; item = item->link) { for (item = g.ntp_peers; item != NULL; item = item->link) {
ntp_peer_t *p = (ntp_peer_t *) item->data; peer_t *p = (peer_t *) item->data;
/* Overflow-safe "if (p->next_action_time <= cur_time) ..." */ /* Overflow-safe "if (p->next_action_time <= cur_time) ..." */
if ((int)(cur_time - p->next_action_time) >= 0) { if ((int)(cur_time - p->next_action_time) >= 0) {
@ -947,9 +949,9 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
timeout = error_interval(); timeout = error_interval();
bb_error_msg("timed out waiting for %s, " bb_error_msg("timed out waiting for %s, "
"next query in %us", p->p_dotted, timeout); "next query in %us", p->p_dotted, timeout);
if (p->trustlevel >= TRUSTLEVEL_BADPEER) { if (p->p_trustlevel >= TRUSTLEVEL_BADPEER) {
p->trustlevel /= 2; p->p_trustlevel /= 2;
if (p->trustlevel < TRUSTLEVEL_BADPEER) if (p->p_trustlevel < TRUSTLEVEL_BADPEER)
bb_error_msg("peer %s now invalid", p->p_dotted); bb_error_msg("peer %s now invalid", p->p_dotted);
} }
set_next(p, timeout); set_next(p, timeout);