ntp_restrict.c revision 316068
159024Sobrien/*
2130561Sobrien * ntp_restrict.c - determine host restrictions
3218822Sdim */
459024Sobrien#ifdef HAVE_CONFIG_H
5218822Sdim#include <config.h>
6218822Sdim#endif
759024Sobrien
8218822Sdim#include <stdio.h>
9218822Sdim#include <sys/types.h>
10218822Sdim
11218822Sdim#include "ntpd.h"
1259024Sobrien#include "ntp_if.h"
13218822Sdim#include "ntp_lists.h"
14218822Sdim#include "ntp_stdlib.h"
15218822Sdim#include "ntp_assert.h"
16218822Sdim
1759024Sobrien/*
18218822Sdim * This code keeps a simple address-and-mask list of hosts we want
19218822Sdim * to place restrictions on (or remove them from). The restrictions
20218822Sdim * are implemented as a set of flags which tell you what the host
21218822Sdim * can't do. There is a subroutine entry to return the flags. The
2259024Sobrien * list is kept sorted to reduce the average number of comparisons
23104834Sobrien * and make sure you get the set of restrictions most specific to
2459024Sobrien * the address.
2559024Sobrien *
2659024Sobrien * The algorithm is that, when looking up a host, it is first assumed
2759024Sobrien * that the default set of restrictions will apply. It then searches
2859024Sobrien * down through the list. Whenever it finds a match it adopts the
2959024Sobrien * match's flags instead. When you hit the point where the sorted
3059024Sobrien * address is greater than the target, you return with the last set of
3159024Sobrien * flags you found. Because of the ordering of the list, the most
3259024Sobrien * specific match will provide the final set of flags.
3359024Sobrien *
3459024Sobrien * This was originally intended to restrict you from sync'ing to your
3559024Sobrien * own broadcasts when you are doing that, by restricting yourself from
3659024Sobrien * your own interfaces. It was also thought it would sometimes be useful
3759024Sobrien * to keep a misbehaving host or two from abusing your primary clock. It
3859024Sobrien * has been expanded, however, to suit the needs of those with more
3959024Sobrien * restrictive access policies.
40218822Sdim */
41218822Sdim/*
4259024Sobrien * We will use two lists, one for IPv4 addresses and one for IPv6
4359024Sobrien * addresses. This is not protocol-independant but for now I can't
4459024Sobrien * find a way to respect this. We'll check this later... JFB 07/2001
4559024Sobrien */
4659024Sobrien#define MASK_IPV6_ADDR(dst, src, msk)					\
47218822Sdim	do {								\
4859024Sobrien		int idx;						\
49218822Sdim		for (idx = 0; idx < (int)COUNTOF((dst)->s6_addr); idx++) { \
50218822Sdim			(dst)->s6_addr[idx] = (src)->s6_addr[idx]	\
51218822Sdim					      & (msk)->s6_addr[idx];	\
5259024Sobrien		}							\
5359024Sobrien	} while (0)
5459024Sobrien
5559024Sobrien/*
5659024Sobrien * We allocate INC_RESLIST{4|6} entries to the free list whenever empty.
5759024Sobrien * Auto-tune these to be just less than 1KB (leaving at least 16 bytes
5859024Sobrien * for allocator overhead).
5959024Sobrien */
6059024Sobrien#define	INC_RESLIST4	((1024 - 16) / V4_SIZEOF_RESTRICT_U)
6159024Sobrien#define	INC_RESLIST6	((1024 - 16) / V6_SIZEOF_RESTRICT_U)
6259024Sobrien
6359024Sobrien/*
6459024Sobrien * The restriction list
6559024Sobrien */
66218822Sdimrestrict_u *restrictlist4;
67218822Sdimrestrict_u *restrictlist6;
6859024Sobrienstatic int restrictcount;	/* count in the restrict lists */
6959024Sobrien
7059024Sobrien/*
7159024Sobrien * The free list and associated counters.  Also some uninteresting
7259024Sobrien * stat counters.
7359024Sobrien */
74218822Sdimstatic restrict_u *resfree4;	/* available entries (free list) */
7559024Sobrienstatic restrict_u *resfree6;
7659024Sobrien
7759024Sobrienstatic u_long res_calls;
7859024Sobrienstatic u_long res_found;
79130561Sobrienstatic u_long res_not_found;
8059024Sobrien
8159024Sobrien/*
8259024Sobrien * Count number of restriction entries referring to RES_LIMITED, to
8359024Sobrien * control implicit activation/deactivation of the MRU monlist.
8459024Sobrien */
8559024Sobrienstatic	u_long res_limited_refcnt;
8659024Sobrien
87218822Sdim/*
88218822Sdim * Our default entries.
89218822Sdim */
9059024Sobrienstatic	restrict_u	restrict_def4;
9159024Sobrienstatic	restrict_u	restrict_def6;
9259024Sobrien
9359024Sobrien/*
94218822Sdim * "restrict source ..." enabled knob and restriction bits.
95218822Sdim */
9659024Sobrienstatic	int		restrict_source_enabled;
97218822Sdimstatic	u_short		restrict_source_flags;
98218822Sdimstatic	u_short		restrict_source_mflags;
9959024Sobrien
100218822Sdim/*
10159024Sobrien * private functions
10259024Sobrien */
103218822Sdimstatic restrict_u *	alloc_res4(void);
10459024Sobrienstatic restrict_u *	alloc_res6(void);
105218822Sdimstatic void		free_res(restrict_u *, int);
106218822Sdimstatic void		inc_res_limited(void);
107218822Sdimstatic void		dec_res_limited(void);
108218822Sdimstatic restrict_u *	match_restrict4_addr(u_int32, u_short);
109218822Sdimstatic restrict_u *	match_restrict6_addr(const struct in6_addr *,
110218822Sdim					     u_short);
111218822Sdimstatic restrict_u *	match_restrict_entry(const restrict_u *, int);
11259024Sobrienstatic int		res_sorts_before4(restrict_u *, restrict_u *);
11359024Sobrienstatic int		res_sorts_before6(restrict_u *, restrict_u *);
114218822Sdim
115218822Sdim
11659024Sobrien/*
117218822Sdim * init_restrict - initialize the restriction data structures
118218822Sdim */
11959024Sobrienvoid
120218822Sdiminit_restrict(void)
121218822Sdim{
12259024Sobrien	/*
123218822Sdim	 * The restriction lists begin with a default entry with address
12459024Sobrien	 * and mask 0, which will match any entry.  The lists are kept
12559024Sobrien	 * sorted by descending address followed by descending mask:
12659024Sobrien	 *
12759024Sobrien	 *   address	  mask
12859024Sobrien	 * 192.168.0.0	255.255.255.0	kod limited noquery nopeer
12959024Sobrien	 * 192.168.0.0	255.255.0.0	kod limited
13059024Sobrien	 * 0.0.0.0	0.0.0.0		kod limited noquery
13159024Sobrien	 *
13259024Sobrien	 * The first entry which matches an address is used.  With the
13359024Sobrien	 * example restrictions above, 192.168.0.0/24 matches the first
13459024Sobrien	 * entry, the rest of 192.168.0.0/16 matches the second, and
13559024Sobrien	 * everything else matches the third (default).
13659024Sobrien	 *
13759024Sobrien	 * Note this achieves the same result a little more efficiently
13859024Sobrien	 * than the documented behavior, which is to keep the lists
13959024Sobrien	 * sorted by ascending address followed by ascending mask, with
14059024Sobrien	 * the _last_ matching entry used.
14159024Sobrien	 *
14259024Sobrien	 * An additional wrinkle is we may have multiple entries with
14359024Sobrien	 * the same address and mask but differing match flags (mflags).
14459024Sobrien	 * At present there is only one, RESM_NTPONLY.  Entries with
14577298Sobrien	 * RESM_NTPONLY are sorted earlier so they take precedence over
14659024Sobrien	 * any otherwise similar entry without.  Again, this is the same
14759024Sobrien	 * behavior as but reversed implementation compared to the docs.
14859024Sobrien	 *
14959024Sobrien	 */
15059024Sobrien	LINK_SLIST(restrictlist4, &restrict_def4, link);
15159024Sobrien	LINK_SLIST(restrictlist6, &restrict_def6, link);
15259024Sobrien	restrictcount = 2;
15359024Sobrien}
15459024Sobrien
15559024Sobrien
15659024Sobrienstatic restrict_u *
15759024Sobrienalloc_res4(void)
15859024Sobrien{
15959024Sobrien	const size_t	cb = V4_SIZEOF_RESTRICT_U;
16059024Sobrien	const size_t	count = INC_RESLIST4;
16159024Sobrien	restrict_u *	rl;
16259024Sobrien	restrict_u *	res;
16359024Sobrien	size_t		i;
16459024Sobrien
16559024Sobrien	UNLINK_HEAD_SLIST(res, resfree4, link);
16659024Sobrien	if (res != NULL)
16759024Sobrien		return res;
16859024Sobrien
16959024Sobrien	rl = eallocarray(count, cb);
17059024Sobrien	/* link all but the first onto free list */
17159024Sobrien	res = (void *)((char *)rl + (count - 1) * cb);
17259024Sobrien	for (i = count - 1; i > 0; i--) {
17359024Sobrien		LINK_SLIST(resfree4, res, link);
17459024Sobrien		res = (void *)((char *)res - cb);
17559024Sobrien	}
17659024Sobrien	INSIST(rl == res);
17759024Sobrien	/* allocate the first */
17859024Sobrien	return res;
17959024Sobrien}
18059024Sobrien
18159024Sobrien
18259024Sobrienstatic restrict_u *
18359024Sobrienalloc_res6(void)
18459024Sobrien{
18559024Sobrien	const size_t	cb = V6_SIZEOF_RESTRICT_U;
18659024Sobrien	const size_t	count = INC_RESLIST6;
18759024Sobrien	restrict_u *	rl;
18859024Sobrien	restrict_u *	res;
18959024Sobrien	size_t		i;
19059024Sobrien
191218822Sdim	UNLINK_HEAD_SLIST(res, resfree6, link);
192218822Sdim	if (res != NULL)
19359024Sobrien		return res;
194218822Sdim
195218822Sdim	rl = eallocarray(count, cb);
196218822Sdim	/* link all but the first onto free list */
197218822Sdim	res = (void *)((char *)rl + (count - 1) * cb);
198218822Sdim	for (i = count - 1; i > 0; i--) {
199218822Sdim		LINK_SLIST(resfree6, res, link);
200218822Sdim		res = (void *)((char *)res - cb);
201218822Sdim	}
202218822Sdim	INSIST(rl == res);
203218822Sdim	/* allocate the first */
204218822Sdim	return res;
205218822Sdim}
206218822Sdim
207218822Sdim
208218822Sdimstatic void
209218822Sdimfree_res(
210218822Sdim	restrict_u *	res,
211218822Sdim	int		v6
212218822Sdim	)
21359024Sobrien{
214218822Sdim	restrict_u **	plisthead;
215218822Sdim	restrict_u *	unlinked;
216218822Sdim
217218822Sdim	restrictcount--;
218218822Sdim	if (RES_LIMITED & res->flags)
219218822Sdim		dec_res_limited();
22059024Sobrien
22159024Sobrien	if (v6)
22259024Sobrien		plisthead = &restrictlist6;
22359024Sobrien	else
224130561Sobrien		plisthead = &restrictlist4;
225130561Sobrien	UNLINK_SLIST(unlinked, *plisthead, res, link, restrict_u);
226130561Sobrien	INSIST(unlinked == res);
227130561Sobrien
228130561Sobrien	if (v6) {
229130561Sobrien		zero_mem(res, V6_SIZEOF_RESTRICT_U);
230130561Sobrien		plisthead = &resfree6;
231130561Sobrien	} else {
23259024Sobrien		zero_mem(res, V4_SIZEOF_RESTRICT_U);
233218822Sdim		plisthead = &resfree4;
234218822Sdim	}
235218822Sdim	LINK_SLIST(*plisthead, res, link);
236218822Sdim}
23759024Sobrien
238
239static void
240inc_res_limited(void)
241{
242	if (!res_limited_refcnt)
243		mon_start(MON_RES);
244	res_limited_refcnt++;
245}
246
247
248static void
249dec_res_limited(void)
250{
251	res_limited_refcnt--;
252	if (!res_limited_refcnt)
253		mon_stop(MON_RES);
254}
255
256
257static restrict_u *
258match_restrict4_addr(
259	u_int32	addr,
260	u_short	port
261	)
262{
263	const int	v6 = 0;
264	restrict_u *	res;
265	restrict_u *	next;
266
267	for (res = restrictlist4; res != NULL; res = next) {
268		next = res->link;
269		if (res->expire &&
270		    res->expire <= current_time)
271			free_res(res, v6);
272		if (res->u.v4.addr == (addr & res->u.v4.mask)
273		    && (!(RESM_NTPONLY & res->mflags)
274			|| NTP_PORT == port))
275			break;
276	}
277	return res;
278}
279
280
281static restrict_u *
282match_restrict6_addr(
283	const struct in6_addr *	addr,
284	u_short			port
285	)
286{
287	const int	v6 = 1;
288	restrict_u *	res;
289	restrict_u *	next;
290	struct in6_addr	masked;
291
292	for (res = restrictlist6; res != NULL; res = next) {
293		next = res->link;
294		INSIST(next != res);
295		if (res->expire &&
296		    res->expire <= current_time)
297			free_res(res, v6);
298		MASK_IPV6_ADDR(&masked, addr, &res->u.v6.mask);
299		if (ADDR6_EQ(&masked, &res->u.v6.addr)
300		    && (!(RESM_NTPONLY & res->mflags)
301			|| NTP_PORT == (int)port))
302			break;
303	}
304	return res;
305}
306
307
308/*
309 * match_restrict_entry - find an exact match on a restrict list.
310 *
311 * Exact match is addr, mask, and mflags all equal.
312 * In order to use more common code for IPv4 and IPv6, this routine
313 * requires the caller to populate a restrict_u with mflags and either
314 * the v4 or v6 address and mask as appropriate.  Other fields in the
315 * input restrict_u are ignored.
316 */
317static restrict_u *
318match_restrict_entry(
319	const restrict_u *	pmatch,
320	int			v6
321	)
322{
323	restrict_u *res;
324	restrict_u *rlist;
325	size_t cb;
326
327	if (v6) {
328		rlist = restrictlist6;
329		cb = sizeof(pmatch->u.v6);
330	} else {
331		rlist = restrictlist4;
332		cb = sizeof(pmatch->u.v4);
333	}
334
335	for (res = rlist; res != NULL; res = res->link)
336		if (res->mflags == pmatch->mflags &&
337		    !memcmp(&res->u, &pmatch->u, cb))
338			break;
339	return res;
340}
341
342
343/*
344 * res_sorts_before4 - compare two restrict4 entries
345 *
346 * Returns nonzero if r1 sorts before r2.  We sort by descending
347 * address, then descending mask, then descending mflags, so sorting
348 * before means having a higher value.
349 */
350static int
351res_sorts_before4(
352	restrict_u *r1,
353	restrict_u *r2
354	)
355{
356	int r1_before_r2;
357
358	if (r1->u.v4.addr > r2->u.v4.addr)
359		r1_before_r2 = 1;
360	else if (r1->u.v4.addr < r2->u.v4.addr)
361		r1_before_r2 = 0;
362	else if (r1->u.v4.mask > r2->u.v4.mask)
363		r1_before_r2 = 1;
364	else if (r1->u.v4.mask < r2->u.v4.mask)
365		r1_before_r2 = 0;
366	else if (r1->mflags > r2->mflags)
367		r1_before_r2 = 1;
368	else
369		r1_before_r2 = 0;
370
371	return r1_before_r2;
372}
373
374
375/*
376 * res_sorts_before6 - compare two restrict6 entries
377 *
378 * Returns nonzero if r1 sorts before r2.  We sort by descending
379 * address, then descending mask, then descending mflags, so sorting
380 * before means having a higher value.
381 */
382static int
383res_sorts_before6(
384	restrict_u *r1,
385	restrict_u *r2
386	)
387{
388	int r1_before_r2;
389	int cmp;
390
391	cmp = ADDR6_CMP(&r1->u.v6.addr, &r2->u.v6.addr);
392	if (cmp > 0)		/* r1->addr > r2->addr */
393		r1_before_r2 = 1;
394	else if (cmp < 0)	/* r2->addr > r1->addr */
395		r1_before_r2 = 0;
396	else {
397		cmp = ADDR6_CMP(&r1->u.v6.mask, &r2->u.v6.mask);
398		if (cmp > 0)		/* r1->mask > r2->mask*/
399			r1_before_r2 = 1;
400		else if (cmp < 0)	/* r2->mask > r1->mask */
401			r1_before_r2 = 0;
402		else if (r1->mflags > r2->mflags)
403			r1_before_r2 = 1;
404		else
405			r1_before_r2 = 0;
406	}
407
408	return r1_before_r2;
409}
410
411
412/*
413 * restrictions - return restrictions for this host
414 */
415u_short
416restrictions(
417	sockaddr_u *srcadr
418	)
419{
420	restrict_u *match;
421	struct in6_addr *pin6;
422	u_short flags;
423
424	res_calls++;
425	flags = 0;
426	/* IPv4 source address */
427	if (IS_IPV4(srcadr)) {
428		/*
429		 * Ignore any packets with a multicast source address
430		 * (this should be done early in the receive process,
431		 * not later!)
432		 */
433		if (IN_CLASSD(SRCADR(srcadr)))
434			return (int)RES_IGNORE;
435
436		match = match_restrict4_addr(SRCADR(srcadr),
437					     SRCPORT(srcadr));
438
439		INSIST(match != NULL);
440
441		match->count++;
442		/*
443		 * res_not_found counts only use of the final default
444		 * entry, not any "restrict default ntpport ...", which
445		 * would be just before the final default.
446		 */
447		if (&restrict_def4 == match)
448			res_not_found++;
449		else
450			res_found++;
451		flags = match->flags;
452	}
453
454	/* IPv6 source address */
455	if (IS_IPV6(srcadr)) {
456		pin6 = PSOCK_ADDR6(srcadr);
457
458		/*
459		 * Ignore any packets with a multicast source address
460		 * (this should be done early in the receive process,
461		 * not later!)
462		 */
463		if (IN6_IS_ADDR_MULTICAST(pin6))
464			return (int)RES_IGNORE;
465
466		match = match_restrict6_addr(pin6, SRCPORT(srcadr));
467		INSIST(match != NULL);
468		match->count++;
469		if (&restrict_def6 == match)
470			res_not_found++;
471		else
472			res_found++;
473		flags = match->flags;
474	}
475	return (flags);
476}
477
478
479/*
480 * hack_restrict - add/subtract/manipulate entries on the restrict list
481 */
482void
483hack_restrict(
484	int		op,
485	sockaddr_u *	resaddr,
486	sockaddr_u *	resmask,
487	u_short		mflags,
488	u_short		flags,
489	u_long		expire
490	)
491{
492	int		v6;
493	restrict_u	match;
494	restrict_u *	res;
495	restrict_u **	plisthead;
496
497	DPRINTF(1, ("restrict: op %d addr %s mask %s mflags %08x flags %08x\n",
498		    op, stoa(resaddr), stoa(resmask), mflags, flags));
499
500	if (NULL == resaddr) {
501		REQUIRE(NULL == resmask);
502		REQUIRE(RESTRICT_FLAGS == op);
503		restrict_source_flags = flags;
504		restrict_source_mflags = mflags;
505		restrict_source_enabled = 1;
506		return;
507	}
508
509	ZERO(match);
510
511#if 0
512	/* silence VC9 potentially uninit warnings */
513	// HMS: let's use a compiler-specific "enable" for this.
514	res = NULL;
515	v6 = 0;
516#endif
517
518	if (IS_IPV4(resaddr)) {
519		v6 = 0;
520		/*
521		 * Get address and mask in host byte order for easy
522		 * comparison as u_int32
523		 */
524		match.u.v4.addr = SRCADR(resaddr);
525		match.u.v4.mask = SRCADR(resmask);
526		match.u.v4.addr &= match.u.v4.mask;
527
528	} else if (IS_IPV6(resaddr)) {
529		v6 = 1;
530		/*
531		 * Get address and mask in network byte order for easy
532		 * comparison as byte sequences (e.g. memcmp())
533		 */
534		match.u.v6.mask = SOCK_ADDR6(resmask);
535		MASK_IPV6_ADDR(&match.u.v6.addr, PSOCK_ADDR6(resaddr),
536			       &match.u.v6.mask);
537
538	} else	/* not IPv4 nor IPv6 */
539		REQUIRE(0);
540
541	match.flags = flags;
542	match.mflags = mflags;
543	match.expire = expire;
544	res = match_restrict_entry(&match, v6);
545
546	switch (op) {
547
548	case RESTRICT_FLAGS:
549		/*
550		 * Here we add bits to the flags. If this is a
551		 * new restriction add it.
552		 */
553		if (NULL == res) {
554			if (v6) {
555				res = alloc_res6();
556				memcpy(res, &match,
557				       V6_SIZEOF_RESTRICT_U);
558				plisthead = &restrictlist6;
559			} else {
560				res = alloc_res4();
561				memcpy(res, &match,
562				       V4_SIZEOF_RESTRICT_U);
563				plisthead = &restrictlist4;
564			}
565			LINK_SORT_SLIST(
566				*plisthead, res,
567				(v6)
568				  ? res_sorts_before6(res, L_S_S_CUR())
569				  : res_sorts_before4(res, L_S_S_CUR()),
570				link, restrict_u);
571			restrictcount++;
572			if (RES_LIMITED & flags)
573				inc_res_limited();
574		} else {
575			if ((RES_LIMITED & flags) &&
576			    !(RES_LIMITED & res->flags))
577				inc_res_limited();
578			res->flags |= flags;
579		}
580		break;
581
582	case RESTRICT_UNFLAG:
583		/*
584		 * Remove some bits from the flags. If we didn't
585		 * find this one, just return.
586		 */
587		if (res != NULL) {
588			if ((RES_LIMITED & res->flags)
589			    && (RES_LIMITED & flags))
590				dec_res_limited();
591			res->flags &= ~flags;
592		}
593		break;
594
595	case RESTRICT_REMOVE:
596	case RESTRICT_REMOVEIF:
597		/*
598		 * Remove an entry from the table entirely if we
599		 * found one. Don't remove the default entry and
600		 * don't remove an interface entry.
601		 */
602		if (res != NULL
603		    && (RESTRICT_REMOVEIF == op
604			|| !(RESM_INTERFACE & res->mflags))
605		    && res != &restrict_def4
606		    && res != &restrict_def6)
607			free_res(res, v6);
608		break;
609
610	default:	/* unknown op */
611		INSIST(0);
612		break;
613	}
614
615}
616
617
618/*
619 * restrict_source - maintains dynamic "restrict source ..." entries as
620 *		     peers come and go.
621 */
622void
623restrict_source(
624	sockaddr_u *	addr,
625	int		farewell,	/* 0 to add, 1 to remove */
626	u_long		expire		/* 0 is infinite, valid until */
627	)
628{
629	sockaddr_u	onesmask;
630	restrict_u *	res;
631	int		found_specific;
632
633	if (!restrict_source_enabled || SOCK_UNSPEC(addr) ||
634	    IS_MCAST(addr) || ISREFCLOCKADR(addr))
635		return;
636
637	REQUIRE(AF_INET == AF(addr) || AF_INET6 == AF(addr));
638
639	SET_HOSTMASK(&onesmask, AF(addr));
640	if (farewell) {
641		hack_restrict(RESTRICT_REMOVE, addr, &onesmask,
642			      0, 0, 0);
643		DPRINTF(1, ("restrict_source: %s removed", stoa(addr)));
644		return;
645	}
646
647	/*
648	 * If there is a specific entry for this address, hands
649	 * off, as it is condidered more specific than "restrict
650	 * server ...".
651	 * However, if the specific entry found is a fleeting one
652	 * added by pool_xmit() before soliciting, replace it
653	 * immediately regardless of the expire value to make way
654	 * for the more persistent entry.
655	 */
656	if (IS_IPV4(addr)) {
657		res = match_restrict4_addr(SRCADR(addr), SRCPORT(addr));
658		INSIST(res != NULL);
659		found_specific = (SRCADR(&onesmask) == res->u.v4.mask);
660	} else {
661		res = match_restrict6_addr(&SOCK_ADDR6(addr),
662					   SRCPORT(addr));
663		INSIST(res != NULL);
664		found_specific = ADDR6_EQ(&res->u.v6.mask,
665					  &SOCK_ADDR6(&onesmask));
666	}
667	if (!expire && found_specific && res->expire) {
668		found_specific = 0;
669		free_res(res, IS_IPV6(addr));
670	}
671	if (found_specific)
672		return;
673
674	hack_restrict(RESTRICT_FLAGS, addr, &onesmask,
675		      restrict_source_mflags, restrict_source_flags,
676		      expire);
677	DPRINTF(1, ("restrict_source: %s host restriction added\n",
678		    stoa(addr)));
679}
680