/*
 * NTP client/server, based on OpenNTPD 3.9p1
 *
 * Author: Adam Tkac <vonsch@gmail.com>
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */
#include "libbb.h"
#include <netinet/ip.h> /* For IPTOS_LOWDELAY definition */
#include <sys/resource.h> /* setpriority */
#ifndef IPTOS_LOWDELAY
# define IPTOS_LOWDELAY 0x10
#endif


/* Sync to peers every N secs */
#define INTERVAL_QUERY_NORMAL    30
#define INTERVAL_QUERY_PATHETIC  60
#define INTERVAL_QUERY_AGRESSIVE  5

/* Bad if *less than* TRUSTLEVEL_BADPEER */
#define TRUSTLEVEL_BADPEER        6
#define TRUSTLEVEL_PATHETIC       2
#define TRUSTLEVEL_AGRESSIVE      8
#define TRUSTLEVEL_MAX           10

#define QSCALE_OFF_MIN         0.05
#define QSCALE_OFF_MAX         0.50

/* Single query might take N secs max */
#define QUERYTIME_MAX            15
/* Min offset for settime at start. "man ntpd" says it's 128 ms */
#define STEPTIME_MIN_OFFSET   0.128

typedef struct {
	uint32_t int_partl;
	uint32_t fractionl;
} l_fixedpt_t;

typedef struct {
	uint16_t int_parts;
	uint16_t fractions;
} s_fixedpt_t;

enum {
	NTP_DIGESTSIZE     = 16,
	NTP_MSGSIZE_NOAUTH = 48,
	NTP_MSGSIZE        = (NTP_MSGSIZE_NOAUTH + 4 + NTP_DIGESTSIZE),
};

typedef struct {
	uint8_t     m_status;     /* status of local clock and leap info */
	uint8_t     m_stratum;    /* stratum level */
	uint8_t     m_ppoll;      /* poll value */
	int8_t      m_precision_exp;
	s_fixedpt_t m_rootdelay;
	s_fixedpt_t m_dispersion;
	uint32_t    m_refid;
	l_fixedpt_t m_reftime;
	l_fixedpt_t m_orgtime;
	l_fixedpt_t m_rectime;
	l_fixedpt_t m_xmttime;
	uint32_t    m_keyid;
	uint8_t     m_digest[NTP_DIGESTSIZE];
} msg_t;

enum {
	NTP_VERSION     = 4,
	NTP_MAXSTRATUM  = 15,

	/* Status Masks */
	MODE_MASK       = (7 << 0),
	VERSION_MASK    = (7 << 3),
	VERSION_SHIFT   = 3,
	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_RES0       = 0,    /* reserved */
	MODE_SYM_ACT    = 1,    /* symmetric active */
	MODE_SYM_PAS    = 2,    /* symmetric passive */
	MODE_CLIENT     = 3,    /* client */
	MODE_SERVER     = 4,    /* server */
	MODE_BROADCAST  = 5,    /* broadcast */
	MODE_RES1       = 6,    /* reserved for NTP control message */
	MODE_RES2       = 7,    /* reserved for private use */
};

#define OFFSET_1900_1970 2208988800UL  /* 1970 - 1900 in seconds */

typedef struct {
	double   d_offset;
	double   d_delay;
	//UNUSED: double d_error;
	time_t   d_rcv_time;
	uint32_t d_refid4;
	uint8_t  d_leap;
	uint8_t  d_stratum;
	uint8_t  d_good;
} datapoint_t;

#define NUM_DATAPOINTS  8
typedef struct {
	len_and_sockaddr *p_lsa;
	char             *p_dotted;
	/* When to send new query (if p_fd == -1)
	 * or when receive times out (if p_fd >= 0): */
	time_t           next_action_time;
	int              p_fd;
	uint8_t          p_datapoint_idx;
	uint8_t          p_trustlevel;
	double           p_xmttime;
	datapoint_t      update;
	datapoint_t      p_datapoint[NUM_DATAPOINTS];
	msg_t            p_xmt_msg;
} peer_t;

enum {
	OPT_n = (1 << 0),
	OPT_q = (1 << 1),
	OPT_N = (1 << 2),
	OPT_x = (1 << 3),
	/* Insert new options above this line. */
	/* Non-compat options: */
	OPT_p = (1 << 4),
	OPT_l = (1 << 5) * ENABLE_FEATURE_NTPD_SERVER,
};


struct globals {
	/* total round trip delay to currently selected reference clock */
	double   rootdelay;
	/* reference timestamp: time when the system clock was last set or corrected */
	double   reftime;
	llist_t  *ntp_peers;
#if ENABLE_FEATURE_NTPD_SERVER
	int      listen_fd;
#endif
	unsigned verbose;
	unsigned peer_cnt;
	unsigned scale;
	uint32_t refid;
	uint32_t refid4;
	uint8_t  synced;
	uint8_t  leap;
#define G_precision_exp -6
//	int8_t   precision_exp;
	uint8_t  stratum;
	uint8_t  time_was_stepped;
	uint8_t  first_adj_done;
};
#define G (*ptr_to_globals)

static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY;


static void
set_next(peer_t *p, unsigned t)
{
	p->next_action_time = time(NULL) + t;
}

static void
add_peers(char *s)
{
	peer_t *p;

	p = xzalloc(sizeof(*p));
	p->p_lsa = xhost2sockaddr(s, 123);
	p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa);
	p->p_fd = -1;
	p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3);
	p->p_trustlevel = TRUSTLEVEL_PATHETIC;
	p->next_action_time = time(NULL); /* = set_next(p, 0); */

	llist_add_to(&G.ntp_peers, p);
	G.peer_cnt++;
}

static double
gettime1900d(void)
{
	struct timeval tv;
	gettimeofday(&tv, NULL); /* never fails */
	return (tv.tv_sec + 1.0e-6 * tv.tv_usec + OFFSET_1900_1970);
}

static void
d_to_tv(double d, struct timeval *tv)
{
	tv->tv_sec = (long)d;
	tv->tv_usec = (d - tv->tv_sec) * 1000000;
}

static double
lfp_to_d(l_fixedpt_t lfp)
{
	double ret;
	lfp.int_partl = ntohl(lfp.int_partl);
	lfp.fractionl = ntohl(lfp.fractionl);
	ret = (double)lfp.int_partl + ((double)lfp.fractionl / UINT_MAX);
	return ret;
}

#if 0 //UNUSED
static double
sfp_to_d(s_fixedpt_t sfp)
{
	double ret;
	sfp.int_parts = ntohs(sfp.int_parts);
	sfp.fractions = ntohs(sfp.fractions);
	ret = (double)sfp.int_parts + ((double)sfp.fractions / USHRT_MAX);
	return ret;
}
#endif

#if ENABLE_FEATURE_NTPD_SERVER
static l_fixedpt_t
d_to_lfp(double d)
{
	l_fixedpt_t lfp;
	lfp.int_partl = (uint32_t)d;
	lfp.fractionl = (uint32_t)((d - lfp.int_partl) * UINT_MAX);
	lfp.int_partl = htonl(lfp.int_partl);
	lfp.fractionl = htonl(lfp.fractionl);
	return lfp;
}

static s_fixedpt_t
d_to_sfp(double d)
{
	s_fixedpt_t sfp;
	sfp.int_parts = (uint16_t)d;
	sfp.fractions = (uint16_t)((d - sfp.int_parts) * USHRT_MAX);
	sfp.int_parts = htons(sfp.int_parts);
	sfp.fractions = htons(sfp.fractions);
	return sfp;
}
#endif

static unsigned
error_interval(void)
{
	unsigned interval, r;
	interval = INTERVAL_QUERY_PATHETIC * QSCALE_OFF_MAX / QSCALE_OFF_MIN;
	r = (unsigned)rand() % (unsigned)(interval / 10);
	return (interval + r);
}

static int
do_sendto(int fd,
		const struct sockaddr *from, const struct sockaddr *to, socklen_t addrlen,
		msg_t *msg, ssize_t len)
{
	ssize_t ret;

	errno = 0;
	if (!from) {
		ret = sendto(fd, msg, len, MSG_DONTWAIT, to, addrlen);
	} else {
		ret = send_to_from(fd, msg, len, MSG_DONTWAIT, to, from, addrlen);
	}
	if (ret != len) {
		bb_perror_msg("send failed");
		return -1;
	}
	return 0;
}

static int
send_query_to_peer(peer_t *p)
{
	// Why do we need to bind()?
	// See what happens when we don't bind:
	//
	// socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
	// setsockopt(3, SOL_IP, IP_TOS, [16], 4) = 0
	// gettimeofday({1259071266, 327885}, NULL) = 0
	// sendto(3, "xxx", 48, MSG_DONTWAIT, {sa_family=AF_INET, sin_port=htons(123), sin_addr=inet_addr("10.34.32.125")}, 16) = 48
	// ^^^ we sent it from some source port picked by kernel.
	// time(NULL)              = 1259071266
	// write(2, "ntpd: entering poll 15 secs\n", 28) = 28
	// poll([{fd=3, events=POLLIN}], 1, 15000) = 1 ([{fd=3, revents=POLLIN}])
	// recv(3, "yyy", 68, MSG_DONTWAIT) = 48
	// ^^^ this recv will receive packets to any local port!
	//
	// Uncomment this and use strace to see it in action:
#define PROBE_LOCAL_ADDR // { len_and_sockaddr lsa; lsa.len = LSA_SIZEOF_SA; getsockname(p->query.fd, &lsa.u.sa, &lsa.len); }

	if (p->p_fd == -1) {
		int fd, family;
		len_and_sockaddr *local_lsa;

		family = p->p_lsa->u.sa.sa_family;
		p->p_fd = fd = xsocket_type(&local_lsa, family, SOCK_DGRAM);
		/* local_lsa has "null" address and port 0 now.
		 * bind() ensures we have a *particular port* selected by kernel
		 * and remembered in p->p_fd, thus later recv(p->p_fd)
		 * receives only packets sent to this port.
		 */
		PROBE_LOCAL_ADDR
		xbind(fd, &local_lsa->u.sa, local_lsa->len);
		PROBE_LOCAL_ADDR
#if ENABLE_FEATURE_IPV6
		if (family == AF_INET)
#endif
			setsockopt(fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY));
		free(local_lsa);
	}

	/*
	 * Send out a random 64-bit number as our transmit time.  The NTP
	 * server will copy said number into the originate field on the
	 * response that it sends us.  This is totally legal per the SNTP spec.
	 *
	 * The impact of this is two fold: we no longer send out the current
	 * system time for the world to see (which may aid an attacker), and
	 * it gives us a (not very secure) way of knowing that we're not
	 * getting spoofed by an attacker that can't capture our traffic
	 * but can spoof packets from the NTP server we're communicating with.
	 *
	 * Save the real transmit timestamp locally.
	 */
	p->p_xmt_msg.m_xmttime.int_partl = rand();
	p->p_xmt_msg.m_xmttime.fractionl = rand();
	p->p_xmttime = gettime1900d();

	if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len,
			&p->p_xmt_msg, NTP_MSGSIZE_NOAUTH) == -1
	) {
		close(p->p_fd);
		p->p_fd = -1;
		set_next(p, INTERVAL_QUERY_PATHETIC);
		return -1;
	}

	if (G.verbose)
		bb_error_msg("sent query to %s", p->p_dotted);
	set_next(p, QUERYTIME_MAX);

	return 0;
}


/* Time is stepped only once, when the first packet from a peer is received.
 */
static void
step_time_once(double offset)
{
	double dtime;
	llist_t *item;
	struct timeval tv;
	char buf[80];
	time_t tval;

	if (G.time_was_stepped)
		goto bail;
	G.time_was_stepped = 1;

	/* if the offset is small, don't step, slew (later) */
	if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET)
		goto bail;

	gettimeofday(&tv, NULL); /* never fails */
	dtime = offset + tv.tv_sec;
	dtime += 1.0e-6 * tv.tv_usec;
	d_to_tv(dtime, &tv);

	if (settimeofday(&tv, NULL) == -1)
		bb_perror_msg_and_die("settimeofday");

	tval = tv.tv_sec;
	strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval);

	bb_error_msg("setting clock to %s (offset %fs)", buf, offset);

	for (item = G.ntp_peers; item != NULL; item = item->link) {
		peer_t *p = (peer_t *) item->data;
		p->next_action_time -= (time_t)offset;
	}

 bail:
	if (option_mask32 & OPT_q)
		exit(0);
}


/* Time is periodically slewed when we collect enough
 * good data points.
 */
static int
compare_offsets(const void *aa, const void *bb)
{
	const peer_t *const *a = aa;
	const peer_t *const *b = bb;
	if ((*a)->update.d_offset < (*b)->update.d_offset)
		return -1;
	return ((*a)->update.d_offset > (*b)->update.d_offset);
}
static unsigned
updated_scale(double offset)
{
	if (offset < 0)
		offset = -offset;
	if (offset > QSCALE_OFF_MAX)
		return 1;
	if (offset < QSCALE_OFF_MIN)
		return QSCALE_OFF_MAX / QSCALE_OFF_MIN;
	return QSCALE_OFF_MAX / offset;
}
static void
slew_time(void)
{
	llist_t *item;
	double offset_median;
	struct timeval tv;

	{
		peer_t **peers = xzalloc(sizeof(peers[0]) * G.peer_cnt);
		unsigned goodpeer_cnt = 0;
		unsigned middle;

		for (item = G.ntp_peers; item != NULL; item = item->link) {
			peer_t *p = (peer_t *) item->data;
			if (p->p_trustlevel < TRUSTLEVEL_BADPEER)
				continue;
			if (!p->update.d_good) {
				free(peers);
				return;
			}
			peers[goodpeer_cnt++] = p;
		}

		if (goodpeer_cnt == 0) {
			free(peers);
			goto clear_good;
		}

		qsort(peers, goodpeer_cnt, sizeof(peers[0]), compare_offsets);

		middle = goodpeer_cnt / 2;
		if (middle != 0 && (goodpeer_cnt & 1) == 0) {
			offset_median = (peers[middle-1]->update.d_offset + peers[middle]->update.d_offset) / 2;
			G.rootdelay = (peers[middle-1]->update.d_delay + peers[middle]->update.d_delay) / 2;
			G.stratum = 1 + MAX(peers[middle-1]->update.d_stratum, peers[middle]->update.d_stratum);
		} else {
			offset_median = peers[middle]->update.d_offset;
			G.rootdelay = peers[middle]->update.d_delay;
			G.stratum = 1 + peers[middle]->update.d_stratum;
		}
		G.leap = peers[middle]->update.d_leap;
		G.refid4 = peers[middle]->update.d_refid4;
		G.refid =
#if ENABLE_FEATURE_IPV6
			peers[middle]->p_lsa->u.sa.sa_family != AF_INET ?
				G.refid4 :
#endif
				peers[middle]->p_lsa->u.sin.sin_addr.s_addr;
		free(peers);
	}
//TODO: if (offset_median > BIG) step_time(offset_median)?

	G.scale = updated_scale(offset_median);

	bb_error_msg("adjusting clock by %fs, our stratum is %u, time scale %u",
			offset_median, G.stratum, G.scale);

	errno = 0;
	d_to_tv(offset_median, &tv);
	if (adjtime(&tv, &tv) == -1)
		bb_perror_msg_and_die("adjtime failed");
	if (G.verbose >= 2)
		bb_error_msg("old adjust: %d.%06u", (int)tv.tv_sec, (unsigned)tv.tv_usec);

	if (G.first_adj_done) {
		uint8_t synced = (tv.tv_sec == 0 && tv.tv_usec == 0);
		if (synced != G.synced) {
			G.synced = synced;
			bb_error_msg("clock is %ssynced", synced ? "" : "un");
		}
	}
	G.first_adj_done = 1;

	G.reftime = gettime1900d();

 clear_good:
	for (item = G.ntp_peers; item != NULL; item = item->link) {
		peer_t *p = (peer_t *) item->data;
		p->update.d_good = 0;
	}
}

static void
update_peer_data(peer_t *p)
{
	/* Clock filter.
	 * Find the datapoint with the lowest delay.
	 * Use that as the peer update.
	 * Invalidate it and all older ones.
	 */
	int i;
	int best = -1;
	int good = 0;

	for (i = 0; i < NUM_DATAPOINTS; i++) {
		if (p->p_datapoint[i].d_good) {
			good++;
			if (best < 0 || p->p_datapoint[i].d_delay < p->p_datapoint[best].d_delay)
				best = i;
		}
	}

	if (good < 8) //FIXME: was it meant to be NUM_DATAPOINTS, not 8?
		return;

	p->update = p->p_datapoint[best]; /* struct copy */
	slew_time();

	for (i = 0; i < NUM_DATAPOINTS; i++)
		if (p->p_datapoint[i].d_rcv_time <= p->p_datapoint[best].d_rcv_time)
			p->p_datapoint[i].d_good = 0;
}

static unsigned
scale_interval(unsigned requested)
{
	unsigned interval, r;
	interval = requested * G.scale;
	r = (unsigned)rand() % (unsigned)(MAX(5, interval / 10));
	return (interval + r);
}
static void
recv_and_process_peer_pkt(peer_t *p)
{
	ssize_t     size;
	msg_t       msg;
	double      T1, T2, T3, T4;
	unsigned    interval;
	datapoint_t *datapoint;

	/* We can recvfrom here and check from.IP, but some multihomed
	 * ntp servers reply from their *other IP*.
	 * TODO: maybe we should check at least what we can: from.port == 123?
	 */
	size = recv(p->p_fd, &msg, sizeof(msg), MSG_DONTWAIT);
	if (size == -1) {
		bb_perror_msg("recv(%s) error", p->p_dotted);
		if (errno == EHOSTUNREACH || errno == EHOSTDOWN
		 || errno == ENETUNREACH || errno == ENETDOWN
		 || errno == ECONNREFUSED || errno == EADDRNOTAVAIL
		 || errno == EAGAIN
		) {
//TODO: always do this?
			set_next(p, error_interval());
			goto close_sock;
		}
		xfunc_die();
	}

	if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) {
		bb_error_msg("malformed packet received from %s", p->p_dotted);
		goto bail;
	}

	if (msg.m_orgtime.int_partl != p->p_xmt_msg.m_xmttime.int_partl
	 || msg.m_orgtime.fractionl != p->p_xmt_msg.m_xmttime.fractionl
	) {
		goto bail;
	}

	if ((msg.m_status & LI_ALARM) == LI_ALARM
	 || msg.m_stratum == 0
	 || msg.m_stratum > NTP_MAXSTRATUM
	) {
// TODO: stratum 0 responses may have commands in 32-bit m_refid field:
// "DENY", "RSTR" - peer does not like us at all
// "RATE" - peer is overloaded, reduce polling freq
		interval = error_interval();
		bb_error_msg("reply from %s: not synced, next query in %us", p->p_dotted, interval);
		goto close_sock;
	}

	/*
	 * From RFC 2030 (with a correction to the delay math):
	 *
	 * Timestamp Name          ID   When Generated
	 * ------------------------------------------------------------
	 * Originate Timestamp     T1   time request sent by client
	 * Receive Timestamp       T2   time request received by server
	 * Transmit Timestamp      T3   time reply sent by server
	 * Destination Timestamp   T4   time reply received by client
	 *
	 * The roundtrip delay and local clock offset are defined as
	 *
	 * delay = (T4 - T1) - (T3 - T2); offset = ((T2 - T1) + (T3 - T4)) / 2
	 */
	T1 = p->p_xmttime;
	T2 = lfp_to_d(msg.m_rectime);
	T3 = lfp_to_d(msg.m_xmttime);
	T4 = gettime1900d();

	datapoint = &p->p_datapoint[p->p_datapoint_idx];

	datapoint->d_offset = ((T2 - T1) + (T3 - T4)) / 2;
	datapoint->d_delay = (T4 - T1) - (T3 - T2);
	if (datapoint->d_delay < 0) {
		bb_error_msg("reply from %s: negative delay %f", p->p_dotted, datapoint->d_delay);
		interval = error_interval();
		set_next(p, interval);
		goto close_sock;
	}
	//UNUSED: datapoint->d_error = (T2 - T1) - (T3 - T4);
	datapoint->d_rcv_time = (time_t)(T4 - OFFSET_1900_1970); /* = time(NULL); */
	datapoint->d_good = 1;

	datapoint->d_leap = (msg.m_status & LI_MASK);
	//UNUSED: datapoint->o_precision = msg.m_precision_exp;
	//UNUSED: datapoint->o_rootdelay = sfp_to_d(msg.m_rootdelay);
	//UNUSED: datapoint->o_rootdispersion = sfp_to_d(msg.m_dispersion);
	//UNUSED: datapoint->d_refid = ntohl(msg.m_refid);
	datapoint->d_refid4 = msg.m_xmttime.fractionl;
	//UNUSED: datapoint->o_reftime = lfp_to_d(msg.m_reftime);
	//UNUSED: datapoint->o_poll = msg.m_ppoll;
	datapoint->d_stratum = msg.m_stratum;

	if (p->p_trustlevel < TRUSTLEVEL_PATHETIC)
		interval = scale_interval(INTERVAL_QUERY_PATHETIC);
	else if (p->p_trustlevel < TRUSTLEVEL_AGRESSIVE)
		interval = scale_interval(INTERVAL_QUERY_AGRESSIVE);
	else
		interval = scale_interval(INTERVAL_QUERY_NORMAL);

	set_next(p, interval);

	/* Every received reply which we do not discard increases trust */
	if (p->p_trustlevel < TRUSTLEVEL_MAX) {
		p->p_trustlevel++;
		if (p->p_trustlevel == TRUSTLEVEL_BADPEER)
			bb_error_msg("peer %s now valid", p->p_dotted);
	}

	if (G.verbose)
		bb_error_msg("reply from %s: offset %f delay %f, next query in %us", p->p_dotted,
			datapoint->d_offset, datapoint->d_delay, interval);

	update_peer_data(p);
//TODO: do it after all peers had a chance to return at least one reply?
	step_time_once(datapoint->d_offset);

	p->p_datapoint_idx++;
	if (p->p_datapoint_idx >= NUM_DATAPOINTS)
		p->p_datapoint_idx = 0;

 close_sock:
	/* We do not expect any more packets from this peer for now.
	 * Closing the socket informs kernel about it.
	 * We open a new socket when we send a new query.
	 */
	close(p->p_fd);
	p->p_fd = -1;
 bail:
	return;
}

#if ENABLE_FEATURE_NTPD_SERVER
static void
recv_and_process_client_pkt(void /*int fd*/)
{
	ssize_t          size;
	uint8_t          version;
	double           rectime;
	len_and_sockaddr *to;
	struct sockaddr  *from;
	msg_t            msg;
	uint8_t          query_status;
	uint8_t          query_ppoll;
	l_fixedpt_t      query_xmttime;

	to = get_sock_lsa(G.listen_fd);
	from = xzalloc(to->len);

	size = recv_from_to(G.listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len);
	if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) {
		char *addr;
		if (size < 0) {
			if (errno == EAGAIN)
				goto bail;
			bb_perror_msg_and_die("recv");
		}
		addr = xmalloc_sockaddr2dotted_noport(from);
		bb_error_msg("malformed packet received from %s: size %u", addr, (int)size);
		free(addr);
		goto bail;
	}

	query_status = msg.m_status;
	query_ppoll = msg.m_ppoll;
	query_xmttime = msg.m_xmttime;

	/* Build a reply packet */
	memset(&msg, 0, sizeof(msg));
	msg.m_status = G.synced ? G.leap : LI_ALARM;
	msg.m_status |= (query_status & VERSION_MASK);
	msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ?
			MODE_SERVER : MODE_SYM_PAS;
	msg.m_stratum = G.stratum;
	msg.m_ppoll = query_ppoll;
	msg.m_precision_exp = G_precision_exp;
	rectime = gettime1900d();
	msg.m_xmttime = msg.m_rectime = d_to_lfp(rectime);
	msg.m_reftime = d_to_lfp(G.reftime);
	//msg.m_xmttime = d_to_lfp(gettime1900d()); // = msg.m_rectime
	msg.m_orgtime = query_xmttime;
	msg.m_rootdelay = d_to_sfp(G.rootdelay);
	version = (query_status & VERSION_MASK); /* ... >> VERSION_SHIFT - done below instead */
	msg.m_refid = (version > (3 << VERSION_SHIFT)) ? G.refid4 : G.refid;

	/* We reply from the local address packet was sent to,
	 * this makes to/from look swapped here: */
	do_sendto(G.listen_fd,
		/*from:*/ &to->u.sa, /*to:*/ from, /*addrlen:*/ to->len,
		&msg, size);

 bail:
	free(to);
	free(from);
}
#endif

/* Upstream ntpd's options:
 *
 * -4   Force DNS resolution of host names to the IPv4 namespace.
 * -6   Force DNS resolution of host names to the IPv6 namespace.
 * -a   Require cryptographic authentication for broadcast client,
 *      multicast client and symmetric passive associations.
 *      This is the default.
 * -A   Do not require cryptographic authentication for broadcast client,
 *      multicast client and symmetric passive associations.
 *      This is almost never a good idea.
 * -b   Enable the client to synchronize to broadcast servers.
 * -c conffile
 *      Specify the name and path of the configuration file,
 *      default /etc/ntp.conf
 * -d   Specify debugging mode. This option may occur more than once,
 *      with each occurrence indicating greater detail of display.
 * -D level
 *      Specify debugging level directly.
 * -f driftfile
 *      Specify the name and path of the frequency file.
 *      This is the same operation as the "driftfile FILE"
 *      configuration command.
 * -g   Normally, ntpd exits with a message to the system log
 *      if the offset exceeds the panic threshold, which is 1000 s
 *      by default. This option allows the time to be set to any value
 *      without restriction; however, this can happen only once.
 *      If the threshold is exceeded after that, ntpd will exit
 *      with a message to the system log. This option can be used
 *      with the -q and -x options. See the tinker command for other options.
 * -i jaildir
 *      Chroot the server to the directory jaildir. This option also implies
 *      that the server attempts to drop root privileges at startup
 *      (otherwise, chroot gives very little additional security).
 *      You may need to also specify a -u option.
 * -k keyfile
 *      Specify the name and path of the symmetric key file,
 *      default /etc/ntp/keys. This is the same operation
 *      as the "keys FILE" configuration command.
 * -l logfile
 *      Specify the name and path of the log file. The default
 *      is the system log file. This is the same operation as
 *      the "logfile FILE" configuration command.
 * -L   Do not listen to virtual IPs. The default is to listen.
 * -n   Don't fork.
 * -N   To the extent permitted by the operating system,
 *      run the ntpd at the highest priority.
 * -p pidfile
 *      Specify the name and path of the file used to record the ntpd
 *      process ID. This is the same operation as the "pidfile FILE"
 *      configuration command.
 * -P priority
 *      To the extent permitted by the operating system,
 *      run the ntpd at the specified priority.
 * -q   Exit the ntpd just after the first time the clock is set.
 *      This behavior mimics that of the ntpdate program, which is
 *      to be retired. The -g and -x options can be used with this option.
 *      Note: The kernel time discipline is disabled with this option.
 * -r broadcastdelay
 *      Specify the default propagation delay from the broadcast/multicast
 *      server to this client. This is necessary only if the delay
 *      cannot be computed automatically by the protocol.
 * -s statsdir
 *      Specify the directory path for files created by the statistics
 *      facility. This is the same operation as the "statsdir DIR"
 *      configuration command.
 * -t key
 *      Add a key number to the trusted key list. This option can occur
 *      more than once.
 * -u user[:group]
 *      Specify a user, and optionally a group, to switch to.
 * -v variable
 * -V variable
 *      Add a system variable listed by default.
 * -x   Normally, the time is slewed if the offset is less than the step
 *      threshold, which is 128 ms by default, and stepped if above
 *      the threshold. This option sets the threshold to 600 s, which is
 *      well within the accuracy window to set the clock manually.
 *      Note: since the slew rate of typical Unix kernels is limited
 *      to 0.5 ms/s, each second of adjustment requires an amortization
 *      interval of 2000 s. Thus, an adjustment as much as 600 s
 *      will take almost 14 days to complete. This option can be used
 *      with the -g and -q options. See the tinker command for other options.
 *      Note: The kernel time discipline is disabled with this option.
 */

/* By doing init in a separate function we decrease stack usage
 * in main loop.
 */
static NOINLINE void ntp_init(char **argv)
{
	unsigned opts;
	llist_t *peers;

	srand(getpid());

	if (getuid())
		bb_error_msg_and_die(bb_msg_you_must_be_root);

	peers = NULL;
	opt_complementary = "dd:p::"; /* d: counter, p: list */
	opts = getopt32(argv,
			"nqNx" /* compat */
			"p:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */
			"d" /* compat */
			"46aAbgL", /* compat, ignored */
			&peers, &G.verbose);
	if (!(opts & (OPT_p|OPT_l)))
		bb_show_usage();
	if (opts & OPT_x) /* disable stepping, only slew is allowed */
		G.time_was_stepped = 1;
	while (peers)
		add_peers(llist_pop(&peers));
	if (!(opts & OPT_n)) {
		bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv);
		logmode = LOGMODE_NONE;
	}
#if ENABLE_FEATURE_NTPD_SERVER
	G.listen_fd = -1;
	if (opts & OPT_l) {
		G.listen_fd = create_and_bind_dgram_or_die(NULL, 123);
		socket_want_pktinfo(G.listen_fd);
		setsockopt(G.listen_fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY));
	}
#endif
	/* I hesitate to set -20 prio. -15 should be high enough for timekeeping */
	if (opts & OPT_N)
		setpriority(PRIO_PROCESS, 0, -15);

	/* Set some globals */
#if 0
	/* With constant b = 100, G.precision_exp is also constant -6.
	 * Uncomment this and you'll see */
	{
		int prec = 0;
		int b;
# if 0
		struct timespec tp;
		/* We can use sys_clock_getres but assuming 10ms tick should be fine */
		clock_getres(CLOCK_REALTIME, &tp);
		tp.tv_sec = 0;
		tp.tv_nsec = 10000000;
		b = 1000000000 / tp.tv_nsec;  /* convert to Hz */
# else
		b = 100; /* b = 1000000000/10000000 = 100 */
# endif
		while (b > 1)
			prec--, b >>= 1;
		//G.precision_exp = prec;
		bb_error_msg("G.precision_exp:%d", prec); /* -6 */
	}
#endif
	G.scale = 1;

	bb_signals((1 << SIGTERM) | (1 << SIGINT), record_signo);
	bb_signals((1 << SIGPIPE) | (1 << SIGHUP), SIG_IGN);
}

int ntpd_main(int argc UNUSED_PARAM, char **argv) MAIN_EXTERNALLY_VISIBLE;
int ntpd_main(int argc UNUSED_PARAM, char **argv)
{
	struct globals g;
	struct pollfd *pfd;
	peer_t **idx2peer;

	memset(&g, 0, sizeof(g));
	SET_PTR_TO_GLOBALS(&g);

	ntp_init(argv);

	{
		/* if ENABLE_FEATURE_NTPD_SERVER, + 1 for listen_fd: */
		unsigned cnt = g.peer_cnt + ENABLE_FEATURE_NTPD_SERVER;
		idx2peer = xzalloc(sizeof(idx2peer[0]) * cnt);
		pfd = xzalloc(sizeof(pfd[0]) * cnt);
	}

	while (!bb_got_signal) {
		llist_t *item;
		unsigned i, j;
		unsigned sent_cnt, trial_cnt;
		int nfds, timeout;
		time_t cur_time, nextaction;

		/* Nothing between here and poll() blocks for any significant time */

		cur_time = time(NULL);
		nextaction = cur_time + 3600;

		i = 0;
#if ENABLE_FEATURE_NTPD_SERVER
		if (g.listen_fd != -1) {
			pfd[0].fd = g.listen_fd;
			pfd[0].events = POLLIN;
			i++;
		}
#endif
		/* Pass over peer list, send requests, time out on receives */
		sent_cnt = trial_cnt = 0;
		for (item = g.ntp_peers; item != NULL; item = item->link) {
			peer_t *p = (peer_t *) item->data;

			/* Overflow-safe "if (p->next_action_time <= cur_time) ..." */
			if ((int)(cur_time - p->next_action_time) >= 0) {
				if (p->p_fd == -1) {
					/* Time to send new req */
					trial_cnt++;
					if (send_query_to_peer(p) == 0)
						sent_cnt++;
				} else {
					/* Timed out waiting for reply */
					close(p->p_fd);
					p->p_fd = -1;
					timeout = error_interval();
					bb_error_msg("timed out waiting for %s, "
							"next query in %us", p->p_dotted, timeout);
					if (p->p_trustlevel >= TRUSTLEVEL_BADPEER) {
						p->p_trustlevel /= 2;
						if (p->p_trustlevel < TRUSTLEVEL_BADPEER)
							bb_error_msg("peer %s now invalid", p->p_dotted);
					}
					set_next(p, timeout);
				}
			}

			if (p->next_action_time < nextaction)
				nextaction = p->next_action_time;

			if (p->p_fd >= 0) {
				/* Wait for reply from this peer */
				pfd[i].fd = p->p_fd;
				pfd[i].events = POLLIN;
				idx2peer[i] = p;
				i++;
			}
		}

		if ((trial_cnt > 0 && sent_cnt == 0) || g.peer_cnt == 0)
			step_time_once(0); /* no good peers, don't wait */

		timeout = nextaction - cur_time;
		if (timeout < 1)
			timeout = 1;

		/* Here we may block */
		if (g.verbose >= 2)
			bb_error_msg("poll %us, sockets:%u", timeout, i);
		nfds = poll(pfd, i, timeout * 1000);
		if (nfds <= 0)
			continue;

		/* Process any received packets */
		j = 0;
#if ENABLE_FEATURE_NTPD_SERVER
		if (g.listen_fd != -1) {
			if (pfd[0].revents /* & (POLLIN|POLLERR)*/) {
				nfds--;
				recv_and_process_client_pkt(/*g.listen_fd*/);
			}
			j = 1;
		}
#endif
		for (; nfds != 0 && j < i; j++) {
			if (pfd[j].revents /* & (POLLIN|POLLERR)*/) {
				nfds--;
				recv_and_process_peer_pkt(idx2peer[j]);
			}
		}
	} /* while (!bb_got_signal) */

	kill_myself_with_sig(bb_got_signal);
}
