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

📄 ntptimeset.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
#  ifndef	LOG_NTP#	define	LOG_NTP LOG_DAEMON#  endif		openlog("ntptimeset", LOG_PID | LOG_NDELAY, LOG_NTP);		if (debug)			setlogmask(LOG_UPTO(LOG_DEBUG));		else			setlogmask(LOG_UPTO(LOG_INFO));# endif /* LOG_DAEMON */#endif	/* SYS_WINNT */	}	if (debug || verbose)		msyslog(LOG_INFO, "%s", Version);	if (horrible)		msyslog(LOG_INFO, "Dropping %d out of %d packets",			horrible,horrible+HORRIBLEOK);	/*	 * Add servers we are going to be polling	 */	loadservers(cfgpath);	if (sys_numservers < min_servers) {		msyslog(LOG_ERR, "Found %d servers, require %d servers",			sys_numservers,min_servers);		exit(2);	}	/*	 * determine when we will end at least 	 */	finish_time = max_period * TIMER_HZ;	half_time = finish_time >> 1;	/*	 * Initialize the time of day routines and the I/O subsystem	 */	if (sys_authenticate) {		init_auth();#ifdef SYS_WINNT		if (!key_file) key_file = KEYFILE;		if (!ExpandEnvironmentStrings(key_file, key_file_storage, MAX_PATH))		{			msyslog(LOG_ERR, "ExpandEnvironmentStrings(%s) failed: %m\n",				key_file);		} else {			key_file = key_file_storage;		}#endif /* SYS_WINNT */		if (!authreadkeys(key_file)) {			msyslog(LOG_ERR, "no key file, exiting");			exit(1);		}		if (!authistrusted(sys_authkey)) {			char buf[10];			(void) sprintf(buf, "%lu", (unsigned long)sys_authkey);			msyslog(LOG_ERR, "authentication key %s unknown", buf);			exit(1);		}	}	init_io();	init_alarm();	/*	 * Set the priority.	 */#ifdef SYS_VXWORKS	taskPrioritySet( taskIdSelf(), NTPDATE_PRIO);#endif#if defined(HAVE_ATT_NICE)	nice (NTPDATE_PRIO);#endif#if defined(HAVE_BSD_NICE)	(void) setpriority(PRIO_PROCESS, 0, NTPDATE_PRIO);#endif#ifdef SYS_WINNT	process_handle = GetCurrentProcess();	if (!SetPriorityClass(process_handle, (DWORD) REALTIME_PRIORITY_CLASS)) {		msyslog(LOG_ERR, "SetPriorityClass failed: %m");	}#endif /* SYS_WINNT */	initializing = 0;	/*	 * Use select() on all on all input fd's for unlimited	 * time.  select() will terminate on SIGALARM or on the	 * reception of input.	Using select() means we can't do	 * robust signal handling and we get a potential race	 * between checking for alarms and doing the select().	 * Mostly harmless, I think.	 * Keep going until we have enough information, or time is up.	 */	/* On VMS, I suspect that select() can't be interrupted	 * by a "signal" either, so I take the easy way out and	 * have select() time out after one second.	 * System clock updates really aren't time-critical,	 * and - lacking a hardware reference clock - I have	 * yet to learn about anything else that is.	 */	was_alarmed = 0;	rbuflist = (struct recvbuf *)0;	while (finish_time > current_time) {#if !defined(HAVE_SIGNALED_IO) 		fd_set rdfdes;		int nfound;#elif defined(HAVE_SIGNALED_IO)		block_io_and_alarm();#endif		rbuflist = getrecvbufs();	/* get received buffers */		if (printmsg) {			printmsg = 0;			analysis(0);		}		if (alarm_flag) {		/* alarmed? */			was_alarmed = 1;			alarm_flag = 0;		}		if (!was_alarmed && rbuflist == (struct recvbuf *)0) {			/*			 * Nothing to do.  Wait for something.			 */#ifndef HAVE_SIGNALED_IO			rdfdes = fdmask;# if defined(VMS) || defined(SYS_VXWORKS)			/* make select() wake up after one second */			{				struct timeval t1;				t1.tv_sec = 1; t1.tv_usec = 0;				nfound = select(fd+1, &rdfdes, (fd_set *)0,						(fd_set *)0, &t1);			}# else			nfound = select(fd+1, &rdfdes, (fd_set *)0,					(fd_set *)0, (struct timeval *)0);# endif /* VMS */			if (nfound > 0) {				l_fp ts;				get_systime(&ts);				(void)input_handler(&ts);			}			else if (nfound == -1 && errno != EINTR)				msyslog(LOG_ERR, "select() error: %m");			else if (debug) {# if !defined SYS_VXWORKS && !defined SYS_CYGWIN32 /* to unclutter log */				msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);# endif			}#else /* HAVE_SIGNALED_IO */                        			wait_for_signal();#endif /* HAVE_SIGNALED_IO */			if (alarm_flag) 	/* alarmed? */			{				was_alarmed = 1;				alarm_flag = 0;			}			rbuflist = getrecvbufs();  /* get received buffers */		}#ifdef HAVE_SIGNALED_IO		unblock_io_and_alarm();#endif /* HAVE_SIGNALED_IO */		/*		 * Out here, signals are unblocked.  Call timer routine		 * to process expiry.		 */		if (was_alarmed)		{			timer();			was_alarmed = 0;		}		/*		 * Call the data procedure to handle each received		 * packet.		 */		while (rbuflist != (struct recvbuf *)0)		{			rbuf = rbuflist;			rbuflist = rbuf->next;			receive(rbuf);			freerecvbuf(rbuf);		}#if defined DEBUG && defined SYS_WINNT		if (debug > 4)		    printf("getrecvbufs: %ld handler interrupts, %ld frames\n",			   handler_calls, handler_pkts);#endif		/*		 * Do we have enough information to stop now?		 */		if (have_enough())			break;	/* time to end */		/*		 * Go around again		 */	}	/*	 * adjust the clock and exit accordingly	 */	set_local_clock();	/*	 * if we get here then we are in trouble	 */	return(1);}/* * analysis - print a message indicating what is happening with time service *	      must mimic have_enough() procedure. */static voidanalysis(	int final	){	if (contacted < sys_numservers) {		printf("%d servers of %d have been probed with %d packets\n",		       contacted,sys_numservers,MINTRANSMITS);		return;	}	if (!responding) {		printf("No response from any of %d servers, network problem?\n",		       sys_numservers);		return;	}	else if (responding < min_servers) {		printf("%d servers out of %d responding, need at least %d.\n",		       responding, sys_numservers, min_servers);		return;	}	if (!validcount) {		printf("%d servers responding but none have valid time\n",		       responding);		return;	}	else if (validcount < min_valid) {		printf("%d servers responding, %d are valid, need %d valid\n",		       responding,validcount,min_valid);		return;	}	if (!final && valid_n_low != validcount) {		printf("%d valid servers but only %d have low dispersion\n",		       validcount,valid_n_low);		return;	}}/* have_enough - see if we have enough information to terminate probing */static inthave_enough(void){	/* have we contacted all servers yet? */	if (contacted < sys_numservers)		return 0;	/* no...try some more */	/* have we got at least minimum servers responding? */	if (responding < min_servers)		return 0;	/* no...try some more */	/* count the clocks */	(void) clock_count();	/* have we got at least minimum valid clocks? */	if (validcount <= 0 || validcount < min_valid)		return 0;	/* no...try some more */	/* do we have all valid servers with low dispersion */	if (!secondhalf && valid_n_low != validcount)		return 0;	/* if we get into the secondhalf then we ignore dispersion */	/* all conditions have been met...end */	return 1;}/* * transmit - transmit a packet to the given server, or mark it completed. *	      This is called by the timeout routine and by the receive *	      procedure. */static voidtransmit(	register struct server *server	){	struct pkt xpkt;	int timeout;	if (debug > 2)		printf("transmit(%s)\n", ntoa(&server->srcadr));	if ((server->reach & 01) == 0) {		l_fp ts;		/*		 * Last message to this server timed out.  Shift		 * zeros into the filter.		 */		L_CLR(&ts);		clock_filter(server, 0, &ts);	}	/*	 * shift reachable register over	 */	server->reach <<= 1;	/*	 * If we're here, send another message to the server.  Fill in	 * the packet and let 'er rip.	 */	xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,		server->version, MODE_CLIENT);	xpkt.stratum = STRATUM_TO_PKT(STRATUM_UNSPEC);	xpkt.ppoll = NTP_MINPOLL;	xpkt.precision = NTPDATE_PRECISION;	xpkt.rootdelay = htonl(NTPDATE_DISTANCE);	xpkt.rootdispersion = htonl(NTPDATE_DISP);	xpkt.refid = htonl(NTPDATE_REFID);	L_CLR(&xpkt.reftime);	L_CLR(&xpkt.org);	L_CLR(&xpkt.rec);	/*	 * Determine whether to authenticate or not.  If so,	 * fill in the extended part of the packet and do it.	 * If not, just timestamp it and send it away.	 */	if (sys_authenticate) {		int len;		xpkt.exten[0] = htonl(sys_authkey);		get_systime(&server->xmt);		L_ADDUF(&server->xmt, sys_authdelay);		HTONL_FP(&server->xmt, &xpkt.xmt);		len = authencrypt(sys_authkey, (u_int32 *)&xpkt, LEN_PKT_NOMAC);		if (sendpkt(&(server->srcadr), &xpkt, (int)(LEN_PKT_NOMAC + len))) {			if (debug > 1)				printf("failed transmit auth to %s\n",				    ntoa(&(server->srcadr)));			return;		}		if (debug > 1)			printf("transmit auth to %s\n",			    ntoa(&(server->srcadr)));	} else {		get_systime(&(server->xmt));		HTONL_FP(&server->xmt, &xpkt.xmt);		if (sendpkt(&(server->srcadr), &xpkt, LEN_PKT_NOMAC)) {			if (debug > 1)				printf("failed transmit to %s\n", 				    ntoa(&(server->srcadr)));			return;		}		if (debug > 1)			printf("transmit to %s\n", ntoa(&(server->srcadr)));	}	/*	 * count transmits, record contacted count and set transmit time	 */	if (++server->xmtcnt == MINTRANSMITS)	    contacted++;	server->last_xmit = current_time;	/*	 * determine timeout for this packet. The more packets we send	 * to the host, the slower we get. If the host indicates that	 * it is not "sane" then we expect even less.	 */	if (server->xmtcnt < MINTRANSMITS) {	    /* we have not sent enough */	    timeout = TIMER_HZ;		/* 1 second probe */	}	else if (server->rcvcnt <= 0) {	    /* we have heard nothing */	    if (secondhalf)		timeout = TIMER_HZ<<4;	/* 16 second probe */	    else		timeout = TIMER_HZ<<3;	/* 8 second probe */	}	else {	    /* if we have low dispersion then probe infrequently */	    if (server->dispersion <= DESIREDDISP)		timeout = TIMER_HZ<<4;	/* 16 second probe */	    /* if the server is not in sync then let it alone */	    else if (server->leap == LEAP_NOTINSYNC)		timeout = TIMER_HZ<<4;	/* 16 second probe */	    /* if the server looks broken ignore it */	    else if (server->org.l_ui < server->reftime.l_ui)		timeout = TIMER_HZ<<5;	/* 32 second probe */	    else if (secondhalf)		timeout = TIMER_HZ<<2;	/* 4 second probe */	    else		timeout = TIMER_HZ<<1;	/* 2 second probe */	}	/*	 * set next transmit time based on timeout	 */	server->event_time = current_time + timeout;}/* * receive - receive and process an incoming frame */static voidreceive(	struct recvbuf *rbufp	){	register struct pkt *rpkt;	register struct server *server;	register s_fp di;	l_fp t10, t23;	l_fp org;	l_fp rec;	l_fp ci;	int has_mac;	int is_authentic;	if (debug > 2)		printf("receive(%s)\n", ntoa(&rbufp->srcadr));	/*	 * Check to see if the packet basically looks like something	 * intended for us.	 */	if (rbufp->recv_length == LEN_PKT_NOMAC)		has_mac = 0;	else if (rbufp->recv_length >= LEN_PKT_NOMAC)		has_mac = 1;	else {		if (debug > 2)			printf("receive: packet length %d\n",			    rbufp->recv_length);		return;		/* funny length packet */	}	rpkt = &(rbufp->recv_pkt);	if (PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION ||	    PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) {		if (debug > 1)			printf("receive: bad version %d\n",			       PKT_VERSION(rpkt->li_vn_mode));		return;	}	if ((PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER	    && PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE)	    || rpkt->stratum >=STRATUM_UNSPEC) {		if (debug > 1)			printf("receive: mode %d stratum %d\n",			    PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);		return;	}		/*	 * So far, so good.  See if this is from a server we know.	 */	server = findserver(&(rbufp->srcadr));	if (server == NULL) {		if (debug > 1)			printf("receive: server not found\n");		return;	}	/*	 * Decode the org timestamp and make sure we're getting a response	 * to our last request.	 */	NTOHL_FP(&rpkt->org, &org);	if (!L_ISEQU(&org, &server->xmt)) {		if (debug > 1)			printf("receive: pkt.org and peer.xmt differ\n");		return;	}		/*	 * Check out the authenticity if we're doing that.	 */	if (!sys_authenticate)		is_authentic = 1;	else {		is_authentic = 0;		if (debug > 3)			printf("receive: rpkt keyid=%ld sys_authkey=%ld decrypt=%ld\n",			   (long int)ntohl(rpkt->exten[0]), (long int)sys_authkey,			   (long int)authdecrypt(sys_authkey, (u_int32 *)rpkt,				LEN_PKT_NOMAC, (int)(rbufp->recv_length - LEN_PKT_NOMAC)));		if (has_mac && ntohl(rpkt->exten[0]) == sys_authkey &&			authdecrypt(sys_authkey, (u_int32 *)rpkt, LEN_PKT_NOMAC,			(int)(rbufp->recv_length - LEN_PKT_NOMAC)))			is_authentic = 1;		if (debug)			printf("receive: authentication %s\n",			   is_authentic ? "passed" : "failed");	}	server->trust <<= 1;	if (!is_authentic)		server->trust |= 1;		/*	 * Looks good.  Record info from the packet.	 */	server->leap = PKT_LEAP(rpkt->li_vn_mode);	server->stratum = PKT_TO_STRATUM(rpkt->stratum);	server->precision = rpkt->precision;	server->rootdelay = ntohl(rpkt->rootdelay);	server->rootdispersion = ntohl(rpkt->rootdispersion);	server->refid = rpkt->refid;	NTOHL_FP(&rpkt->reftime, &server->reftime);	NTOHL_FP(&rpkt->rec, &rec);	NTOHL_FP(&rpkt->xmt, &server->org);	/*	 * count this guy as responding	 */	server->reach |= 1;	if (server->rcvcnt++ == 0)		responding++;	/*

⌨️ 快捷键说明

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