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

📄 ntp_peer.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * We do a dirty little jig to figure the cast flags. This is	 * probably not the best place to do this, at least until the	 * configure code is rebuilt. Note only one flag can be set.	 */	switch (hmode) {	case MODE_BROADCAST:		if(srcadr->ss_family == AF_INET) {			if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr)))				cast_flags = MDF_MCAST;			else				cast_flags = MDF_BCAST;			break;		}		else {                        if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr))        	                cast_flags = MDF_MCAST;	        	else                        	cast_flags = MDF_BCAST;                	break;                }	case MODE_CLIENT:		if(srcadr->ss_family == AF_INET) {			if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr)))				cast_flags = MDF_ACAST;			else				cast_flags = MDF_UCAST;			break;		}		else {			if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr))				cast_flags = MDF_ACAST;			else				cast_flags = MDF_UCAST;			break;		}	default:		cast_flags = MDF_UCAST;	}	/*	 * If the peer is already configured, some dope has a duplicate	 * configureation entry or another dope is wiggling from afar.	 */	if (peer != 0) {		peer->hmode = (u_char)hmode;		peer->version = (u_char) version;		peer->minpoll = (u_char) minpoll;		peer->maxpoll = (u_char) maxpoll;		peer->flags = flags | FLAG_CONFIG |			(peer->flags & FLAG_REFCLOCK);		peer->cast_flags = cast_flags;		peer->ttl = (u_char) ttl;		peer->keyid = key;		peer->precision = sys_precision;		peer_clear(peer, "RMOT");		return (peer);	}	/*	 * Here no match has been found, so presumably this is a new	 * persistent association. Mobilize the thing and initialize its	 * variables. If emulating ntpdate, force iburst.	 */	if (mode_ntpdate)		flags |= FLAG_IBURST;	peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,	    flags | FLAG_CONFIG, cast_flags, ttl, key);	return (peer);}/* * newpeer - initialize a new peer association */struct peer *newpeer(	struct sockaddr_storage *srcadr,	struct interface *dstadr,	int hmode,	int version,	int minpoll,	int maxpoll,	u_int flags,	u_char cast_flags,	int ttl,	keyid_t key	){	register struct peer *peer;	register int i;#ifdef OPENSSL	char	statstr[NTP_MAXSTRLEN]; /* statistics for filegen */#endif /* OPENSSL */	/*	 * Allocate a new peer structure. Some dirt here, since some of	 * the initialization requires knowlege of our system state.	 */	if (peer_free_count == 0)		getmorepeermem();	peer = peer_free;	peer_free = peer->next;	peer_free_count--;	peer_associations++;	if (flags & FLAG_PREEMPT)		peer_preempt++;	memset((char *)peer, 0, sizeof(struct peer));	/*	 * Assign an association ID and increment the system variable.	 */	peer->associd = current_association_ID;	if (++current_association_ID == 0)		++current_association_ID;#ifdef DEBUG	if (debug >2)		printf("newpeer: cast flags: 0x%x for address: %s\n",			cast_flags, stoa(srcadr));#endif	/*	 * Initialize the peer structure and dance the interface jig.	 * Reference clocks step the loopback waltz, the others	 * squaredance around the interface list looking for a buddy. If	 * the dance peters out, there is always the wildcard interface.	 * This might happen in some systems and would preclude proper	 * operation with public key cryptography.	 */	if (ISREFCLOCKADR(srcadr))		peer->dstadr = loopback_interface;	else if (cast_flags & (MDF_BCLNT | MDF_ACAST | MDF_MCAST | MDF_BCAST)) {		peer->dstadr = findbcastinter(srcadr);#ifdef DEBUG		if (debug > 1) {			if (peer->dstadr != NULL)				printf("Found broadcast interface address %s, for address %s\n",					stoa(&(peer->dstadr)->sin), stoa(srcadr));			else				printf("No broadcast local address found for address %s\n",					stoa(srcadr));		}#endif		/*		 * If it was a multicast packet, findbcastinter() may not		 * find it, so try a little harder.		 */		if (peer->dstadr == ANY_INTERFACE_CHOOSE(srcadr))			peer->dstadr = findinterface(srcadr);	} else if (dstadr != NULL && dstadr != ANY_INTERFACE_CHOOSE(srcadr))		peer->dstadr = dstadr;	else		peer->dstadr = findinterface(srcadr);	/*	 * If we can't find an interface to use we return a NULL	 */	if (peer->dstadr == NULL)	{		msyslog(LOG_ERR, "Cannot find suitable interface for address %s", stoa(srcadr));		return (NULL);	}	/*	 * Broadcast needs the socket enabled for broadcast	 */	if (cast_flags & MDF_BCAST) {		enable_broadcast(peer->dstadr, srcadr);	}	/*	 * Multicast needs the socket interface enabled for multicast	 */	if (cast_flags & MDF_MCAST) {		enable_multicast_if(peer->dstadr, srcadr);	}#ifdef DEBUG	if (debug>2)		printf("newpeer: using fd %d and our addr %s\n",		    peer->dstadr->fd, stoa(&peer->dstadr->sin));#endif	peer->srcadr = *srcadr;	peer->hmode = (u_char)hmode;	peer->version = (u_char)version;	peer->minpoll = (u_char)max(NTP_MINPOLL, minpoll);	peer->maxpoll = (u_char)min(NTP_MAXPOLL, maxpoll);	peer->flags = flags;	if (key != 0)		peer->flags |= FLAG_AUTHENABLE;	if (key > NTP_MAXKEY)		peer->flags |= FLAG_SKEY;	peer->cast_flags = cast_flags;	peer->ttl = (u_char)ttl;	peer->keyid = key;	peer->precision = sys_precision;	peer->hpoll = peer->minpoll;	if (cast_flags & MDF_ACAST)		peer_clear(peer, "ACST");	else if (cast_flags & MDF_MCAST)		peer_clear(peer, "MCST");	else if (cast_flags & MDF_BCAST)		peer_clear(peer, "BCST");	else		peer_clear(peer, "INIT");	if (mode_ntpdate)		peer_ntpdate++;	/*	 * Note time on statistics timers.	 */	peer->timereset = current_time;	peer->timereachable = current_time;	peer->timereceived = current_time;#ifdef REFCLOCK	if (ISREFCLOCKADR(&peer->srcadr)) {		/*		 * We let the reference clock support do clock		 * dependent initialization.  This includes setting		 * the peer timer, since the clock may have requirements		 * for this.		 */		if (!refclock_newpeer(peer)) {			/*			 * Dump it, something screwed up			 */			peer->next = peer_free;			peer_free = peer;			peer_free_count++;			return (NULL);		}	}#endif	/*	 * Put the new peer in the hash tables.	 */	i = NTP_HASH_ADDR(&peer->srcadr);	peer->next = peer_hash[i];	peer_hash[i] = peer;	peer_hash_count[i]++;	i = peer->associd & NTP_HASH_MASK;	peer->ass_next = assoc_hash[i];	assoc_hash[i] = peer;	assoc_hash_count[i]++;#ifdef OPENSSL	if (peer->flags & FLAG_SKEY) {		sprintf(statstr, "newpeer %d", peer->associd);		record_crypto_stats(&peer->srcadr, statstr);#ifdef DEBUG		if (debug)			printf("peer: %s\n", statstr);#endif	}#endif /* OPENSSL */#ifdef DEBUG	if (debug)		printf(		    "newpeer: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x\n",		    peer->dstadr == NULL ? "null" : stoa(&peer->dstadr->sin),		    stoa(&peer->srcadr),		    peer->hmode, peer->version, peer->minpoll,		    peer->maxpoll, peer->flags, peer->cast_flags,		    peer->ttl, peer->keyid);#endif	return (peer);}/* * peer_unconfig - remove the configuration bit from a peer */intpeer_unconfig(	struct sockaddr_storage *srcadr,	struct interface *dstadr,	int mode	){	register struct peer *peer;	int num_found;	num_found = 0;	peer = findexistingpeer(srcadr, (struct peer *)0, mode);	while (peer != 0) {		if (peer->flags & FLAG_CONFIG		    && (dstadr == 0 || peer->dstadr == dstadr)) {			num_found++;			/*			 * Tricky stuff here. If the peer is polling us			 * in active mode, turn off the configuration			 * bit and make the mode passive. This allows us			 * to avoid dumping a lot of history for peers			 * we might choose to keep track of in passive			 * mode. The protocol will eventually terminate			 * undesirables on its own.			 */			if (peer->hmode == MODE_ACTIVE			    && peer->pmode == MODE_ACTIVE) {				peer->hmode = MODE_PASSIVE;				peer->flags &= ~FLAG_CONFIG;			} else {				unpeer(peer);				peer = 0;			}		}		peer = findexistingpeer(srcadr, peer, mode);	}	return (num_found);}/* * peer_clr_stats - clear peer module stat counters */voidpeer_clr_stats(void){	findpeer_calls = 0;	assocpeer_calls = 0;	peer_allocations = 0;	peer_demobilizations = 0;	peer_timereset = current_time;}/* * peer_reset - reset stat counters in a peer structure */voidpeer_reset(	struct peer *peer	){	if (peer == 0)	    return;	peer->sent = 0;	peer->received = 0;	peer->processed = 0;	peer->badauth = 0;	peer->bogusorg = 0;	peer->oldpkt = 0;	peer->seldisptoolarge = 0;	peer->timereset = current_time;}/* * peer_all_reset - reset all peer stat counters */voidpeer_all_reset(void){	struct peer *peer;	int hash;	for (hash = 0; hash < NTP_HASH_SIZE; hash++)	    for (peer = peer_hash[hash]; peer != 0; peer = peer->next)		peer_reset(peer);}#ifdef OPENSSL/* * expire_all - flush all crypto data and update timestamps. */voidexpire_all(void){	struct peer *peer, *next_peer;	int n;	/*	 * This routine is called about once per day from the timer	 * routine and when the client is first synchronized. Search the	 * peer list for all associations and flush only the key list	 * and cookie. If a manycast client association, flush	 * everything. Then, recompute and sign the agreement public	 * value, if present.	 */	if (!crypto_flags)		return;	for (n = 0; n < NTP_HASH_SIZE; n++) {		for (peer = peer_hash[n]; peer != 0; peer = next_peer) {			next_peer = peer->next;			if (!(peer->flags & FLAG_SKEY)) {				continue;			} else if (peer->hmode == MODE_ACTIVE ||			    peer->hmode == MODE_PASSIVE) {				key_expire(peer);				peer->crypto &= ~(CRYPTO_FLAG_AUTO |				    CRYPTO_FLAG_AGREE);			}						}	}	RAND_bytes((u_char *)&sys_private, 4);	crypto_update();}#endif /* OPENSSL *//* * findmanycastpeer - find and return a manycast peer */struct peer *findmanycastpeer(	struct recvbuf *rbufp	){	register struct peer *peer;	struct pkt *pkt;	l_fp p_org;	int i; 	/* 	 * This routine is called upon arrival of a server-mode message	 * from a manycast client. Search the peer list for a manycast	 * client association where the last transmit timestamp matches	 * the originate timestamp. This assumes the transmit timestamps	 * for possibly more than one manycast association are unique.	 */	pkt = &rbufp->recv_pkt;	for (i = 0; i < NTP_HASH_SIZE; i++) {		if (peer_hash_count[i] == 0)			continue;		for (peer = peer_hash[i]; peer != 0; peer =		    peer->next) {			if (peer->cast_flags & MDF_ACAST) {				NTOHL_FP(&pkt->org, &p_org);				if (L_ISEQU(&peer->xmt, &p_org))					return (peer);			}		}	}	return (NULL);}

⌨️ 快捷键说明

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