0
  +   ˆl–Ãa¾”ji?u@?pÜŠbÑ¿È„‚ÛŸ_†I|¥�+ÂÇ /|    /*
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
 *
 * See the COPYRIGHT file distributed with this work for additional
 * information regarding copyright ownership.
 */

#ifndef DNS_RPZ_H
#define DNS_RPZ_H 1

#include <inttypes.h>
#include <stdbool.h>

#include <isc/deprecated.h>
#include <isc/event.h>
#include <isc/ht.h>
#include <isc/lang.h>
#include <isc/refcount.h>
#include <isc/rwlock.h>
#include <isc/time.h>
#include <isc/timer.h>

#include <dns/fixedname.h>
#include <dns/rdata.h>
#include <dns/types.h>

ISC_LANG_BEGINDECLS

#define DNS_RPZ_PREFIX "rpz-"
/*
 * Sub-zones of various trigger types.
 */
#define DNS_RPZ_CLIENT_IP_ZONE DNS_RPZ_PREFIX "client-ip"
#define DNS_RPZ_IP_ZONE	       DNS_RPZ_PREFIX "ip"
#define DNS_RPZ_NSIP_ZONE      DNS_RPZ_PREFIX "nsip"
#define DNS_RPZ_NSDNAME_ZONE   DNS_RPZ_PREFIX "nsdname"
/*
 * Special policies.
 */
#define DNS_RPZ_PASSTHRU_NAME DNS_RPZ_PREFIX "passthru"
#define DNS_RPZ_DROP_NAME     DNS_RPZ_PREFIX "drop"
#define DNS_RPZ_TCP_ONLY_NAME DNS_RPZ_PREFIX "tcp-only"

typedef uint8_t dns_rpz_prefix_t;

typedef enum {
	DNS_RPZ_TYPE_BAD,
	DNS_RPZ_TYPE_CLIENT_IP,
	DNS_RPZ_TYPE_QNAME,
	DNS_RPZ_TYPE_IP,
	DNS_RPZ_TYPE_NSDNAME,
	DNS_RPZ_TYPE_NSIP
} dns_rpz_type_t;

/*
 * Require DNS_RPZ_POLICY_PASSTHRU < DNS_RPZ_POLICY_DROP
 * < DNS_RPZ_POLICY_TCP_ONLY DNS_RPZ_POLICY_NXDOMAIN < DNS_RPZ_POLICY_NODATA
 * < DNS_RPZ_POLICY_CNAME to choose among competing policies.
 */
typedef enum {
	DNS_RPZ_POLICY_GIVEN = 0,    /* 'given': what policy record says */
	DNS_RPZ_POLICY_DISABLED = 1, /* log what would have happened */
	DNS_RPZ_POLICY_PASSTHRU = 2, /* 'passthru': do not rewrite */
	DNS_RPZ_POLICY_DROP = 3,     /* 'drop': do not respond */
	DNS_RPZ_POLICY_TCP_ONLY = 4, /* 'tcp-only': answer UDP with TC=1 */
	DNS_RPZ_POLICY_NXDOMAIN = 5, /* 'nxdomain': answer with NXDOMAIN */
	DNS_RPZ_POLICY_NODATA = 6,   /* 'nodata': answer with ANCOUNT=0 */
	DNS_RPZ_POLICY_CNAME = 7,    /* 'cname x': answer with x's rrsets */
	DNS_RPZ_POLICY_DNS64,	     /* Apply DN64 to the A rewrite */
	DNS_RPZ_POLICY_RECORD,
	DNS_RPZ_POLICY_WILDCNAME,
	DNS_RPZ_POLICY_MISS,
	DNS_RPZ_POLICY_ERROR
} dns_rpz_policy_t;

typedef uint8_t dns_rpz_num_t;

#define DNS_RPZ_MAX_ZONES 64
/*
 * Type dns_rpz_zbits_t must be an unsigned int wide enough to contain
 * at least DNS_RPZ_MAX_ZONES bits.
 */
typedef uint64_t dns_rpz_zbits_t;

#define DNS_RPZ_ALL_ZBITS ((dns_rpz_zbits_t)-1)

#define DNS_RPZ_INVALID_NUM DNS_RPZ_MAX_ZONES

#define DNS_RPZ_ZBIT(n) (((dns_rpz_zbits_t)1) << (dns_rpz_num_t)(n))

/*
 * Mask of the specified and higher numbered policy zones
 * Avoid hassles with (1<<33) or (1<<65)
 */
#define DNS_RPZ_ZMASK(n)                                     \
	((dns_rpz_zbits_t)((((n) >= DNS_RPZ_MAX_ZONES - 1)   \
				    ? 0                      \
				    : (1ULL << ((n) + 1))) - \
			   1))

/*
 * The trigger counter type.
 */
typedef size_t dns_rpz_trigger_counter_t;

/*
 * The number of triggers of each type in a response policy zone.
 */
typedef struct dns_rpz_triggers dns_rpz_triggers_t;
struct dns_rpz_triggers {
	dns_rpz_trigger_counter_t client_ipv4;
	dns_rpz_trigger_counter_t client_ipv6;
	dns_rpz_trigger_counter_t qname;
	dns_rpz_trigger_counter_t ipv4;
	dns_rpz_trigger_counter_t ipv6;
	dns_rpz_trigger_counter_t nsdname;
	dns_rpz_trigger_counter_t nsipv4;
	dns_rpz_trigger_counter_t nsipv6;
};

/*
 * A single response policy zone.
 */
typedef struct dns_rpz_zone  dns_rpz_zone_t;
typedef struct dns_rpz_zones dns_rpz_zones_t;

struct dns_rpz_zone {
	isc_refcount_t	 refs;
	dns_rpz_num_t	 num;	    /* ordinal in list of policy zones */
	dns_name_t	 origin;    /* Policy zone name */
	dns_name_t	 client_ip; /* DNS_RPZ_CLIENT_IP_ZONE.origin. */
	dns_name_t	 ip;	    /* DNS_RPZ_IP_ZONE.origin. */
	dns_name_t	 nsdname;   /* DNS_RPZ_NSDNAME_ZONE.origin */
	dns_na