FreeBSD/contrib/ntp/ntpd/ntp_peer.c
/*
 * findpeer - find and return a peer match for a received datagram in
 *	      the peer_hash table.
 *
 * [Bug 3072] To faciliate a faster reorganisation after routing changes
 * the original code re-assigned the peer address to be the destination
 * of the received packet and initiated another round on a mismatch.
 * Unfortunately this leaves us wide open for a DoS attack where the
 * attacker directs a packet with forged destination address to us --
 * this results in a wrong interface assignment, actually creating a DoS
 * situation.
 *
 * This condition would persist until the next update of the interface
 * list, but a continued attack would put us out of business again soon
 * enough. Authentication alone does not help here, since it does not
 * protect the UDP layer and leaves us open for a replay attack.
 *
 * So we do not update the adresses and wait until the next interface
 * list update does the right thing for us.
 */
find and return a peer match for a received datagram in
the peer_hash table.

[Bug 3072] To faciliate a faster reorganisation after routing changes
the original code re-assigned the peer address to be the destination
of the received packet and initiated another round on a mismatch.
Unfortunately this leaves us wide open for a DoS attack where the
attacker directs a packet with forged destination address to us
this results in a wrong interface assignment, actually creating a DoS
situation.

This condition would persist until the next update of the interface
list, but a continued attack would put us out of business again soon
enough. Authentication alone does not help here, since it does not
protect the UDP layer and leaves us open for a replay attack.

So we do not update the adresses and wait until the next interface
list update does the right thing for us.
find and return a peer match for a received datagram in the peer_hash table . [ Bug 3072 ] To faciliate a faster reorganisation after routing changes the original code re - assigned the peer address to be the destination of the received packet and initiated another round on a mismatch . Unfortunately this leaves us wide open for a DoS attack where the attacker directs a packet with forged destination address to us this results in a wrong interface assignment actually creating a DoS situation . This condition would persist until the next update of the interface list but a continued attack would put us out of business again soon enough . Authentication alone does not help here since it does not protect the UDP layer and leaves us open for a replay attack . So we do not update the adresses and wait until the next interface list update does the right thing for us .
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 (p->dstadr != rbufp->dstadr)
			continue;
		if ( ! ADDR_PORT_EQ(srcadr, &p->srcadr))
			continue;
		*action = MATCH_ASSOC(p->hmode, pkt_mode);
		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 (*action == AM_ERR)
			return NULL;
		if (*action != AM_NOMATCH)
			break;
	}
	if (NULL == p)
		*action = MATCH_ASSOC(NO_PEER, pkt_mode);
	return p;
}
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 ( p -> dstadr != rbufp -> dstadr ) continue ; if ( ! ADDR_PORT_EQ ( srcadr , & p -> srcadr ) ) continue ; * action = MATCH_ASSOC ( p -> hmode , pkt_mode ) ; 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 ( * action == AM_ERR ) return NULL ; if ( * action != AM_NOMATCH ) break ; } if ( NULL == p ) * action = MATCH_ASSOC ( NO_PEER , pkt_mode ) ; return p ; }
findpeer - find and return a peer match for a received datagram in
            the peer_hash table.
findpeer - find and return a peer match for a received datagram in the peer_hash table .
/* [Bug 3072] ensure interface of peer matches */ /* ensure peer source address matches */ /* If the association matching rules determine that this
		 * is not a valid combination, then look for the next
		 * valid peer association.
		 */ /* 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 an error was returned, exit back right here. */ /* if a match is found, we stop our search. */ /* If no matching association is found... */