Exemplo n.º 1
0
/*
 * findpeer - find and return a peer in the hash table.
 */
struct peer *
findpeer(
	struct sockaddr_storage *srcadr,
	struct interface *dstadr,
	int	pkt_mode,
	int	*action
	)
{
	register struct peer *peer;
	int hash;

	findpeer_calls++;
	hash = NTP_HASH_ADDR(srcadr);
	for (peer = peer_hash[hash]; peer != NULL; peer = peer->next) {
		if (SOCKCMP(srcadr, &peer->srcadr) &&
		    NSRCPORT(srcadr) == NSRCPORT(&peer->srcadr)) {

			/*
			 * if the association matching rules determine
			 * that this is not a valid combination, then
			 * look for the next valid peer association.
			 */
			*action = MATCH_ASSOC(peer->hmode, pkt_mode);

			/*
			 * if an error was returned, exit back right
			 * here.
			 */
			if (*action == AM_ERR)
				return ((struct peer *)0);

			/*
			 * if a match is found, we stop our search.
			 */
			if (*action != AM_NOMATCH)
				break;
		}
	}

	/*
	 * If no matching association is found
	 */
	if (peer == 0) {
		*action = MATCH_ASSOC(NO_PEER, pkt_mode);
		return ((struct peer *)0);
	}

	set_peerdstadr(peer, dstadr);

	return (peer);
}
Exemplo n.º 2
0
/*
 * unpeer - remove peer structure from hash table and free structure
 */
void
unpeer(
	struct peer *peer
	)
{
	mprintf_event(PEVNT_DEMOBIL, peer, "assoc %u", peer->associd);
	restrict_source(&peer->srcadr, 1, 0);
	set_peerdstadr(peer, NULL);
	peer_demobilizations++;
	peer_associations--;
	if (FLAG_PREEMPT & peer->flags)
		peer_preempt--;
#ifdef REFCLOCK
	/*
	 * If this peer is actually a clock, shut it down first
	 */
	if (FLAG_REFCLOCK & peer->flags)
		refclock_unpeer(peer);
#endif

	free_peer(peer, TRUE);
}
Exemplo n.º 3
0
/*
 * unpeer - remove peer structure from hash table and free structure
 */
void
unpeer(
	struct peer *peer_to_remove
	)
{
	int hash;
#ifdef OPENSSL
	char	statstr[NTP_MAXSTRLEN]; /* statistics for filegen */

	if (peer_to_remove->flags & FLAG_SKEY) {
		sprintf(statstr, "unpeer %d flash %x reach %03o flags %04x",
		    peer_to_remove->associd, peer_to_remove->flash,
		    peer_to_remove->reach, peer_to_remove->flags);
		record_crypto_stats(&peer_to_remove->srcadr, statstr);
#ifdef DEBUG
		if (debug)
			printf("peer: %s\n", statstr);
#endif
	}
#endif /* OPENSSL */
#ifdef DEBUG
	if (debug)
		printf("demobilize %u %d %d\n", peer_to_remove->associd,
		    peer_associations, peer_preempt);
#endif
	set_peerdstadr(peer_to_remove, NULL);

	/* XXXMEMLEAK? peer_clear->crypto allocation */

	hash = NTP_HASH_ADDR(&peer_to_remove->srcadr);
	peer_hash_count[hash]--;
	peer_demobilizations++;
	peer_associations--;
	if (peer_to_remove->flags & FLAG_PREEMPT)
		peer_preempt--;
#ifdef REFCLOCK
	/*
	 * If this peer is actually a clock, shut it down first
	 */
	if (peer_to_remove->flags & FLAG_REFCLOCK)
		refclock_unpeer(peer_to_remove);
#endif
	peer_to_remove->action = 0;	/* disable timeout actions */
	if (peer_hash[hash] == peer_to_remove)
		peer_hash[hash] = peer_to_remove->next;
	else {
		register struct peer *peer;

		peer = peer_hash[hash];
		while (peer != 0 && peer->next != peer_to_remove)
		    peer = peer->next;
		
		if (peer == 0) {
			peer_hash_count[hash]++;
			msyslog(LOG_ERR, "peer struct for %s not in table!",
				stoa(&peer->srcadr));
		} else {
			peer->next = peer_to_remove->next;
		}
	}

	/*
	 * Remove him from the association hash as well.
	 */
	hash = peer_to_remove->associd & NTP_HASH_MASK;
	assoc_hash_count[hash]--;
	if (assoc_hash[hash] == peer_to_remove)
		assoc_hash[hash] = peer_to_remove->ass_next;
	else {
		register struct peer *peer;

		peer = assoc_hash[hash];
		while (peer != 0 && peer->ass_next != peer_to_remove)
		    peer = peer->ass_next;
		
		if (peer == 0) {
			assoc_hash_count[hash]++;
			msyslog(LOG_ERR,
				"peer struct for %s not in association table!",
				stoa(&peer->srcadr));
		} else {
			peer->ass_next = peer_to_remove->ass_next;
		}
	}
	peer_to_remove->next = peer_free;
	peer_free = peer_to_remove;
	peer_free_count++;
}
Exemplo n.º 4
0
/*
 * findpeer - find and return a peer match for a received datagram in
 *	      the peer_hash table.
 */
struct peer *
findpeer(
	struct recvbuf *rbufp,
	int		pkt_mode,
	int *		action
	)
{
	struct peer *	p;
	sockaddr_u *	srcadr;
	u_int		hash;
	struct pkt *	pkt;
	l_fp		pkt_org;

	findpeer_calls++;
	srcadr = &rbufp->recv_srcadr;
	hash = NTP_HASH_ADDR(srcadr);
	for (p = peer_hash[hash]; p != NULL; p = p->adr_link) {
		if (ADDR_PORT_EQ(srcadr, &p->srcadr)) {

			/*
			 * if the association matching rules determine
			 * that this is not a valid combination, then
			 * look for the next valid peer association.
			 */
			*action = MATCH_ASSOC(p->hmode, pkt_mode);

			/*
			 * A response to our manycastclient solicitation
			 * might be misassociated with an ephemeral peer
			 * already spun for the server.  If the packet's
			 * org timestamp doesn't match the peer's, check
			 * if it matches the ACST prototype peer's.  If
			 * so it is a redundant solicitation response,
			 * return AM_ERR to discard it.  [Bug 1762]
			 */
			if (MODE_SERVER == pkt_mode &&
			    AM_PROCPKT == *action) {
				pkt = &rbufp->recv_pkt;
				NTOHL_FP(&pkt->org, &pkt_org);
				if (!L_ISEQU(&p->aorg, &pkt_org) &&
				    findmanycastpeer(rbufp))
					*action = AM_ERR;
			}

			/*
			 * if an error was returned, exit back right
			 * here.
			 */
			if (*action == AM_ERR)
				return NULL;

			/*
			 * if a match is found, we stop our search.
			 */
			if (*action != AM_NOMATCH)
				break;
		}
	}

	/*
	 * If no matching association is found
	 */
	if (NULL == p) {
		*action = MATCH_ASSOC(NO_PEER, pkt_mode);
	} else if (p->dstadr != rbufp->dstadr) {
		set_peerdstadr(p, rbufp->dstadr);
		if (p->dstadr == rbufp->dstadr) {
			DPRINTF(1, ("Changed %s local address to match response\n",
				    stoa(&p->srcadr)));
			return findpeer(rbufp, pkt_mode, action);
		}
	}
	return p;
}