⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntptimeset.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * Make sure the server is at least somewhat sane.  If not, ignore	 * it for later.	 */	if (L_ISZERO(&rec) || !L_ISHIS(&server->org, &rec)) {		if (debug > 1)			printf("receive: pkt insane\n");		return;	}	/*	 * Calculate the round trip delay (di) and the clock offset (ci).	 * We use the equations (reordered from those in the spec):	 *	 * d = (t2 - t3) - (t1 - t0)	 * c = ((t2 - t3) + (t1 - t0)) / 2	 */	t10 = server->org;		/* pkt.xmt == t1 */	L_SUB(&t10, &rbufp->recv_time);	/* recv_time == t0*/	t23 = rec;			/* pkt.rec == t2 */	L_SUB(&t23, &org);		/* pkt->org == t3 */	/* now have (t2 - t3) and (t0 - t1).  Calculate (ci) and (di) */	ci = t10;	L_ADD(&ci, &t23);	L_RSHIFT(&ci);	/*	 * Calculate di in t23 in full precision, then truncate	 * to an s_fp.	 */	L_SUB(&t23, &t10);	di = LFPTOFP(&t23);	if (debug > 3)		printf("offset: %s, delay %s\n", lfptoa(&ci, 6), fptoa(di, 5));	di += (FP_SECOND >> (-(int)NTPDATE_PRECISION))	    + (FP_SECOND >> (-(int)server->precision)) + NTP_MAXSKW;	if (di <= 0) {		/* value still too raunchy to use? */		L_CLR(&ci);		di = 0;	} else {		di = max(di, NTP_MINDIST);	}	/*	 * This one is valid.  Give it to clock_filter(),	 */	clock_filter(server, di, &ci);	if (debug > 1)		printf("receive from %s\n", ntoa(&rbufp->srcadr));	/*	 * See if we should goes the transmission. If not return now	 * otherwise have the next event time be shortened	 */	if (server->stratum <= NTP_INFIN)	    return;	/* server does not have a stratum */	if (server->leap == LEAP_NOTINSYNC)	    return;	/* just booted server or out of sync */	if (!L_ISHIS(&server->org, &server->reftime))	    return;	/* broken host */	if (server->trust != 0)	    return;	/* can not trust it */	if (server->dispersion < DESIREDDISP)	    return;	/* we have the desired dispersion */	server->event_time -= (TIMER_HZ+1);}/* * clock_filter - add clock sample, determine a server's delay, dispersion *                and offset */static voidclock_filter(	register struct server *server,	s_fp di,	l_fp *c	){	register int i, j;	int ord[NTP_SHIFT];	/*	 * Insert sample and increment nextpt	 */	i = server->filter_nextpt;	server->filter_delay[i] = di;	server->filter_offset[i] = *c;	server->filter_soffset[i] = LFPTOFP(c);	server->filter_nextpt++;	if (server->filter_nextpt >= NTP_SHIFT)		server->filter_nextpt = 0;	/*	 * Sort indices into increasing delay order	 */	for (i = 0; i < NTP_SHIFT; i++)		ord[i] = i;		for (i = 0; i < (NTP_SHIFT-1); i++) {		for (j = i+1; j < NTP_SHIFT; j++) {			if (server->filter_delay[ord[j]] == 0)				continue;			if (server->filter_delay[ord[i]] == 0			    || (server->filter_delay[ord[i]]			    > server->filter_delay[ord[j]])) {				register int tmp;				tmp = ord[i];				ord[i] = ord[j];				ord[j] = tmp;			}		}	}	/*	 * Now compute the dispersion, and assign values to delay and	 * offset.  If there are no samples in the register, delay and	 * offset go to zero and dispersion is set to the maximum.	 */	if (server->filter_delay[ord[0]] == 0) {		server->delay = 0;		L_CLR(&server->offset);		server->soffset = 0;		server->dispersion = PEER_MAXDISP;	} else {		register s_fp d;		server->delay = server->filter_delay[ord[0]];		server->offset = server->filter_offset[ord[0]];		server->soffset = LFPTOFP(&server->offset);		server->dispersion = 0;		for (i = 1; i < NTP_SHIFT; i++) {			if (server->filter_delay[ord[i]] == 0)				d = PEER_MAXDISP;			else {				d = server->filter_soffset[ord[i]]				    - server->filter_soffset[ord[0]];				if (d < 0)					d = -d;				if (d > PEER_MAXDISP)					d = PEER_MAXDISP;			}			/*			 * XXX This *knows* PEER_FILTER is 1/2			 */			server->dispersion += (u_fp)(d) >> i;		}	}	/*	 * We're done	 */}/* clock_count - count the clock sources we have */static voidclock_count(void){	register struct server *server;	register int n;	/* reset counts */	validcount = valid_n_low = 0;	/* go through the list of servers and count the clocks we believe	 * and that have low dispersion	 */	for (n = 0; n < sys_numservers; n++) {		server = sys_servers[n];		if (server->delay == 0) {			continue;	/* no data */		}		if (server->stratum > NTP_INFIN) {			continue;	/* stratum no good */		}		if (server->delay > NTP_MAXWGT) {			continue;	/* too far away */		}		if (server->leap == LEAP_NOTINSYNC)			continue;	/* he's in trouble */		if (!L_ISHIS(&server->org, &server->reftime)) {			continue;	/* very broken host */		}		if ((server->org.l_ui - server->reftime.l_ui) >= NTP_MAXAGE) {			continue;	/* too long without sync */		}		if (server->trust != 0) {			continue;		}		/*		 * This one is a valid time source..		 */		validcount++;		/*		 * See if this one has a okay low dispersion		 */		if (server->dispersion <= DESIREDDISP)		    valid_n_low++;	}	if (debug > 1)		printf("have %d, valid %d, low %d\n",			responding, validcount, valid_n_low);}/* * clock_select - select the pick-of-the-litter clock from the samples *		  we've got. */static struct server *clock_select(void){	register struct server *server;	register int i;	register int nlist;	register s_fp d;	register int j;	register int n;	s_fp local_threshold;	struct server *server_list[NTP_MAXCLOCK];	u_fp server_badness[NTP_MAXCLOCK];	struct server *sys_server;	/*	 * This first chunk of code is supposed to go through all	 * servers we know about to find the NTP_MAXLIST servers which	 * are most likely to succeed.  We run through the list	 * doing the sanity checks and trying to insert anyone who	 * looks okay.  We are at all times aware that we should	 * only keep samples from the top two strata and we only need	 * NTP_MAXLIST of them.	 */	nlist = 0;	/* none yet */	for (n = 0; n < sys_numservers; n++) {		server = sys_servers[n];		if (server->delay == 0)			continue;	/* no data */		if (server->stratum > NTP_INFIN)			continue;	/* stratum no good */		if (server->delay > NTP_MAXWGT) {			continue;	/* too far away */		}		if (server->leap == LEAP_NOTINSYNC)			continue;	/* he's in trouble */		if (!L_ISHIS(&server->org, &server->reftime)) {			continue;	/* very broken host */		}		if ((server->org.l_ui - server->reftime.l_ui)		    >= NTP_MAXAGE) {			continue;	/* too long without sync */		}		if (server->trust != 0) {			continue;		}		/*		 * This one seems sane.  Find where he belongs		 * on the list.		 */		d = server->dispersion + server->dispersion;		for (i = 0; i < nlist; i++)			if (server->stratum <= server_list[i]->stratum)				break;		for ( ; i < nlist; i++) {			if (server->stratum < server_list[i]->stratum)				break;			if (d < (s_fp) server_badness[i])				break;		}		/*		 * If i points past the end of the list, this		 * guy is a loser, else stick him in.		 */		if (i >= NTP_MAXLIST)			continue;		for (j = nlist; j > i; j--)			if (j < NTP_MAXLIST) {				server_list[j] = server_list[j-1];				server_badness[j]				    = server_badness[j-1];			}		server_list[i] = server;		server_badness[i] = d;		if (nlist < NTP_MAXLIST)			nlist++;	}	/*	 * Got the five-or-less best.  Cut the list where the number of	 * strata exceeds two.	 */	j = 0;	for (i = 1; i < nlist; i++)		if (server_list[i]->stratum > server_list[i-1]->stratum)			if (++j == 2) {				nlist = i;				break;			}	/*	 * Whew!  What we should have by now is 0 to 5 candidates for	 * the job of syncing us.  If we have none, we're out of luck.	 * If we have one, he's a winner.  If we have more, do falseticker	 * detection.	 */	if (nlist == 0)		sys_server = 0;	else if (nlist == 1) {		sys_server = server_list[0];	} else {		/*		 * Re-sort by stratum, bdelay estimate quality and		 * server.delay.		 */		for (i = 0; i < nlist-1; i++)			for (j = i+1; j < nlist; j++) {				if (server_list[i]->stratum				    < server_list[j]->stratum)					break;	/* already sorted by stratum */				if (server_list[i]->delay				    < server_list[j]->delay)					continue;				server = server_list[i];				server_list[i] = server_list[j];				server_list[j] = server;			}				/*		 * Calculate the fixed part of the dispersion limit		 */		local_threshold = (FP_SECOND >> (-(int)NTPDATE_PRECISION))		    + NTP_MAXSKW;		/*		 * Now drop samples until we're down to one.		 */		while (nlist > 1) {			for (n = 0; n < nlist; n++) {				server_badness[n] = 0;				for (j = 0; j < nlist; j++) {					if (j == n)	/* with self? */						continue;					d = server_list[j]->soffset					    - server_list[n]->soffset;					if (d < 0)	/* absolute value */						d = -d;					/*					 * XXX This code *knows* that					 * NTP_SELECT is 3/4					 */					for (i = 0; i < j; i++)						d = (d>>1) + (d>>2);					server_badness[n] += d;				}			}			/*			 * We now have an array of nlist badness			 * coefficients.  Find the badest.  Find			 * the minimum precision while we're at			 * it.			 */			i = 0;			n = server_list[0]->precision;;			for (j = 1; j < nlist; j++) {				if (server_badness[j] >= server_badness[i])					i = j;				if (n > server_list[j]->precision)					n = server_list[j]->precision;			}						/*			 * i is the index of the server with the worst			 * dispersion.  If his dispersion is less than			 * the threshold, stop now, else delete him and			 * continue around again.			 */			if (server_badness[i] < (local_threshold						 + (FP_SECOND >> (-n))))				break;			for (j = i + 1; j < nlist; j++)				server_list[j-1] = server_list[j];			nlist--;		}		/*		 * What remains is a list of less than 5 servers.  Take		 * the best.		 */		sys_server = server_list[0];	}	/*	 * That's it.  Return our server.	 */	return sys_server;}/* * set_local_clock -- handle setting the local clock or displaying info. */static voidset_local_clock(void){	register int i;	register struct server *server;	time_t tmp;	double dtemp;	/*	 * if setting time then print final analysis	 */	if (set_time)	    analysis(1);	/*	 * pick a clock	 */	server = clock_select();	/*	 * do some display of information	 */	if (debug || verbose) {		for (i = 0; i < sys_numservers; i++)			printserver(sys_servers[i], stdout);		if (debug)			printf("packets sent %ld, received %ld\n",				total_xmit, total_recv);	}	/*	 * see if we have a server to set the time with	 */	if (server == 0) {	    if (!set_time || verbose)		fprintf(stdout,"No servers available to sync time with\n");	    exit(1);	}	/*	 * we have a valid and selected time to use!!!!!	 */	/*	 * if we are not setting the time then display offset and exit	 */	if (!set_time) {		fprintf(stdout,			"Your clock is off by %s seconds. (%s) [%ld/%ld]\n",			lfptoa(&server->offset, 7),			ntoa(&server->srcadr),			total_xmit, total_recv);		exit(0);	}	/*	 * set the clock	 * XXX: Examine the more flexible approach used by ntpdate.	 * Note that a design consideration here is that we sometimes	 * _want_ to step the clock by a _huge_ amount in either	 * direction, because the local clock is completely bogus.	 * This condition must be recognized and dealt with, so	 * that we always get a good time when this completes.	 * -- jhutz+@cmu.edu, 16-Aug-1999	 */	LFPTOD(&server->offset, dtemp);	step_systime(dtemp);	time(&tmp);	fprintf(stdout,"Time set to %.20s [%s %s %ld/%ld]\n",		ctime(&tmp)+4,		ntoa(&server->srcadr),		lfptoa(&server->offset, 7),		total_xmit, total_recv);	exit(0);}/* * findserver - find a server in the list given its address */static struct server *findserver(	struct sockaddr_in *addr	){	register int i;	register u_int32 netnum;	if (htons(addr->sin_port) != NTP_PORT)		return 0;	netnum = addr->sin_addr.s_addr;	for (i = 0; i < sys_numservers; i++) {		if (netnum == sys_servers[i]->srcadr.sin_addr.s_addr)			return sys_servers[i];	}	return 0;}/* * timer - process a timer interrupt */static voidtimer(void){	register int k;	/*	 * Bump the current idea of the time	 */	current_time++;	/*	 * see if we have reached half time	 */	if (current_time >= half_time && !secondhalf) {	    secondhalf++;	    if (debug)		printf("\nSecond Half of Timeout!\n");	    printmsg++;	}	/*	 * We only want to send a few packets per transmit interrupt

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -