<commit_before>/*
 * Copyright (C) 1999  Internet Software Consortium.
 * 
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> 
#include <errno.h>
#include <string.h>

#include <sys/types.h>

#include <isc/assertions.h>
#include <isc/error.h>
#include <isc/mem.h>
#include <isc/net.h>
#include <isc/result.h>
#include <isc/buffer.h>

#include <dns/db.h>
#include <dns/dbiterator.h>
#include <dns/fixedname.h>
#include <dns/journal.h>
#include <dns/log.h>
#include <dns/name.h>
#include <dns/rdata.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
#include <dns/result.h>
#include <dns/types.h>

/*
 * When true, accept IXFR difference sequences where the
 * SOA serial number does not change (BIND 8 sends such
 * sequences).
 */
static isc_boolean_t bind8_compat = ISC_TRUE; /* XXX config */

/**************************************************************************/
/*
 * Miscellaneous utilities.
 */

#define JOURNAL_COMMON_LOGARGS \
	dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_JOURNAL

#define JOURNAL_DEBUG_LOGARGS(n) \
	JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(n)

#define FAIL(code) do { result = (code); goto failure; } while (0)

#define CHECK(op) \
     	do { result = (op); 					\
		if (result != ISC_R_SUCCESS) goto failure; 	\
	} while (0)

/* XXX should be macros */

static isc_uint32_t
decode_uint32(unsigned char *p) {
	return ((p[0] << 24) +
		(p[1] << 16) +
		(p[2] <<  8) +
		(p[3] <<  0));
}

static void 
encode_uint32(isc_uint32_t val, unsigned char *p) {
	p[0] = (isc_uint8_t)(val >> 24);
	p[1] = (isc_uint8_t)(val >> 16);
	p[2] = (isc_uint8_t)(val >>  8);
	p[3] = (isc_uint8_t)(val >>  0);
}

static dns_rdatatype_t
rdata_covers(dns_rdata_t *rdata) {
	return (rdata->type == dns_rdatatype_sig ?
		dns_rdata_covers(rdata) : 0);
}

isc_uint32_t
dns_soa_getserial(dns_rdata_t *rdata)
{
	INSIST(rdata->type == dns_rdatatype_soa);
	/*
	 * Locate the serial number within the SOA RDATA based
	 * on its position relative to the end of the data.
	 * (it starts 20 bytes from the end).  This is a bit of
	 * a kludge, but the alternative approach of using
	 * dns_rdata_tostruct() and dns_rdata_fromstruct()
	 * would involve a lot of unnecessary work (like 
	 * building domain names and allocating temporary memory)
	 * when all we really want to do is to change 32 bits of
	 * fixed-sized data.  Besides, fromstruct_soa() is not
	 * implemented yet.
	 */
	INSIST(rdata->length > 20);
	return (decode_uint32(rdata->data + rdata->length - 20));
}

void
dns_soa_setserial(isc_uint32_t val, dns_rdata_t *rdata)
{
	INSIST(rdata->type == dns_rdatatype_soa);
	INSIST(rdata->length > 20);
	encode_uint32(val, rdata->data + rdata->length - 20);
}

isc_result_t
dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp)
{
	isc_result_t result;
	dns_dbnode_t *node = NULL;
	dns_rdataset_t rdataset;
	dns_rdata_t rdata;

	REQUIRE(dns_db_iszone(db));
		
	result = dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node);
	if (result != DNS_R_SUCCESS)
		return (result);

	dns_rdataset_init(&rdataset);
	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
				     (isc_stdtime_t) 0, &rdataset, NULL);
 	if (result != DNS_R_SUCCESS)
		goto freenode;
	
	result = dns_rdataset_first(&rdataset);
 	if (result != DNS_R_SUCCESS)
		goto freerdataset;
	dns_rdataset_current(&rdataset, &rdata);

	*serialp = dns_soa_getserial(&rdata);
	result = DNS_R_SUCCESS;

 freerdataset:
	dns_rdataset_disassociate(&rdataset);
	
 freenode:
	dns_db_detachnode(db, &node);
	return (result);
}

isc_result_t
dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
		      dns_diffop_t op, dns_difftuple_t **tp)
{
	isc_result_t result;
	dns_dbnode_t *node;
	dns_rdataset_t rdataset;
	dns_rdata_t rdata;
	dns_name_t *zonename;
	dns_rdataclass_t zoneclass;
	
	zonename = dns_db_origin(db);
	zoneclass = dns_db_class(db);
	
	node = NULL;
	result = dns_db_findnode(db, zonename, ISC_FALSE, &node);
	if (result != DNS_R_SUCCESS)
		return (result);
	
	dns_rdataset_init(&rdataset);
	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
				     (isc_stdtime_t) 0, &rdataset, NULL);
 	if (result != DNS_R_SUCCESS)
		goto freenode;
	
	result = dns_rdataset_first(&rdataset);
 	if (result != DNS_R_SUCCESS)
		goto freenode;

	dns_rdataset_current(&rdataset, &rdata);

	result = dns_difftuple_create(mctx, op, zonename, rdataset.ttl,
				      &rdata, tp);

	dns_rdataset_disassociate(&rdataset);
 freenode:
	dns_db_detachnode(db, &node);
	
	return (result);
}

/**************************************************************************/
/*
 * Diffs, aka Pending Journal Entries.
 */

isc_result_t
dns_difftuple_create(isc_mem_t *mctx,
		     dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
		     dns_rdata_t *rdata, dns_difftuple_t **tp)
{
	dns_difftuple_t *t;
	unsigned int size;
	unsigned char *datap;

	REQUIRE(tp != NULL && *tp == NULL);
	
	/*
	 * Create a new tuple.  The variable-size wire-format name data and
	 * rdata immediately follow the dns_difftuple_t structure
	 * in memory.
	 */
	size = sizeof(*t) + name->length + rdata->length;
	t = isc_mem_allocate(mctx, size);
	if (t == NULL)
		return (DNS_R_NOMEMORY);<commit_msg>warn if SOA RR is unexpectedly missing from a zone<commit_after>/*
 * Copyright (C) 1999  Internet Software Consortium.
 * 
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> 
#include <errno.h>
#include <string.h>

#include <sys/types.h>

#include <isc/assertions.h>
#include <isc/error.h>
#include <isc/mem.h>
#include <isc/net.h>
#include <isc/result.h>
#include <isc/buffer.h>

#include <dns/db.h>
#include <dns/dbiterator.h>
#include <dns/fixedname.h>
#include <dns/journal.h>
#include <dns/log.h>
#include <dns/name.h>
#include <dns/rdata.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
#include <dns/result.h>
#include <dns/types.h>

/*
 * When true, accept IXFR difference sequences where the
 * SOA serial number does not change (BIND 8 sends such
 * sequences).
 */
static isc_boolean_t bind8_compat = ISC_TRUE; /* XXX config */

/**************************************************************************/
/*
 * Miscellaneous utilities.
 */

#define JOURNAL_COMMON_LOGARGS \
	dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_JOURNAL

#define JOURNAL_DEBUG_LOGARGS(n) \
	JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(n)

#define FAIL(code) do { result = (code); goto failure; } while (0)

#define CHECK(op) \
     	do { result = (op); 					\
		if (result != ISC_R_SUCCESS) goto failure; 	\
	} while (0)

/* XXX should be macros */

static isc_uint32_t
decode_uint32(unsigned char *p) {
	return ((p[0] << 24) +
		(p[1] << 16) +
		(p[2] <<  8) +
		(p[3] <<  0));
}

static void 
encode_uint32(isc_uint32_t val, unsigned char *p) {
	p[0] = (isc_uint8_t)(val >> 24);
	p[1] = (isc_uint8_t)(val >> 16);
	p[2] = (isc_uint8_t)(val >>  8);
	p[3] = (isc_uint8_t)(val >>  0);
}

static dns_rdatatype_t
rdata_covers(dns_rdata_t *rdata) {
	return (rdata->type == dns_rdatatype_sig ?
		dns_rdata_covers(rdata) : 0);
}

isc_uint32_t
dns_soa_getserial(dns_rdata_t *rdata)
{
	INSIST(rdata->type == dns_rdatatype_soa);
	/*
	 * Locate the serial number within the SOA RDATA based
	 * on its position relative to the end of the data.
	 * (it starts 20 bytes from the end).  This is a bit of
	 * a kludge, but the alternative approach of using
	 * dns_rdata_tostruct() and dns_rdata_fromstruct()
	 * would involve a lot of unnecessary work (like 
	 * building domain names and allocating temporary memory)
	 * when all we really want to do is to change 32 bits of
	 * fixed-sized data.  Besides, fromstruct_soa() is not
	 * implemented yet.
	 */
	INSIST(rdata->length > 20);
	return (decode_uint32(rdata->data + rdata->length - 20));
}

void
dns_soa_setserial(isc_uint32_t val, dns_rdata_t *rdata)
{
	INSIST(rdata->type == dns_rdatatype_soa);
	INSIST(rdata->length > 20);
	encode_uint32(val, rdata->data + rdata->length - 20);
}

isc_result_t
dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp)
{
	isc_result_t result;
	dns_dbnode_t *node = NULL;
	dns_rdataset_t rdataset;
	dns_rdata_t rdata;

	REQUIRE(dns_db_iszone(db));
		
	result = dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node);
	if (result != DNS_R_SUCCESS)
		return (result);

	dns_rdataset_init(&rdataset);
	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
				     (isc_stdtime_t) 0, &rdataset, NULL);
 	if (result != DNS_R_SUCCESS)
		goto freenode;
	
	result = dns_rdataset_first(&rdataset);
 	if (result != DNS_R_SUCCESS)
		goto freerdataset;
	dns_rdataset_current(&rdataset, &rdata);

	*serialp = dns_soa_getserial(&rdata);
	result = DNS_R_SUCCESS;

 freerdataset:
	dns_rdataset_disassociate(&rdataset);
	
 freenode:
	dns_db_detachnode(db, &node);
	return (result);
}

isc_result_t
dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
		      dns_diffop_t op, dns_difftuple_t **tp)
{
	isc_result_t result;
	dns_dbnode_t *node;
	dns_rdataset_t rdataset;
	dns_rdata_t rdata;
	dns_name_t *zonename;
	dns_rdataclass_t zoneclass;
	
	zonename = dns_db_origin(db);
	zoneclass = dns_db_class(db);
	
	node = NULL;
	result = dns_db_findnode(db, zonename, ISC_FALSE, &node);
	if (result != DNS_R_SUCCESS)
		goto nonode;
	
	dns_rdataset_init(&rdataset);
	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
				     (isc_stdtime_t) 0, &rdataset, NULL);
 	if (result != DNS_R_SUCCESS)
		goto freenode;
	
	result = dns_rdataset_first(&rdataset);
 	if (result != DNS_R_SUCCESS)
		goto freenode;

	dns_rdataset_current(&rdataset, &rdata);

	result = dns_difftuple_create(mctx, op, zonename, rdataset.ttl,
				      &rdata, tp);

	dns_rdataset_disassociate(&rdataset);
	return (ISC_R_SUCCESS);

 freenode:
	dns_db_detachnode(db, &node);
 nonode:
	UNEXPECTED_ERROR(__FILE__, __LINE__, "missing SOA");
	return (result);
}

/**************************************************************************/
/*
 * Diffs, aka Pending Journal Entries.
 */

isc_result_t
dns_difftuple_create(isc_mem_t *mctx,
		     dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
		     dns_rdata_t *rdata, dns_difftuple_t **tp)
{
	dns_difftuple_t *t;
	unsigned int size;
	unsigned char *datap;

	REQUIRE(tp != NULL && *tp == NULL);
	
	/*
	 * Create a new tuple.  The variable-size wire-format name data and
	 * rdata immediately follow the dns_difftuple_t structure
	 * in memory.
	 */
	size = sizeof(*t) + name->length + rdata->length;
	t = isc_mem_allocate(mctx, size);
	if (t == NULL)
		return (DNS_R_NOMEMORY);
{'fraction_non_alphanumeric': 0.13940337649565646, 'fraction_numerical': 0.010981806261268644, 'mean_word_length': 4.620912022109627, 'pattern_counts': {'":': 0, '<': 71, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3695037', 'n_tokens_mistral': 5029, 'n_tokens_neox': 4761, 'n_words': 1169}