mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 14:07:59 +00:00
[master] add hash to map files
3562. [func] Update map file header format to include a SHA-1 hash of the database content, so that corrupted map files can be rejected at load time. [RT #32459]
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -1,3 +1,7 @@
|
|||||||
|
3562. [func] Update map file header format to include a SHA-1 hash
|
||||||
|
of the database content, so that corrupted map files
|
||||||
|
can be rejected at load time. [RT #32459]
|
||||||
|
|
||||||
3561. [bug] dig: issue a warning if an EDNS query returns FORMERR
|
3561. [bug] dig: issue a warning if an EDNS query returns FORMERR
|
||||||
or NOTIMP. Adjust usage message. [RT #33363]
|
or NOTIMP. Adjust usage message. [RT #33363]
|
||||||
|
|
||||||
|
@@ -31,5 +31,4 @@ rm -f ns2/formerly-text.db
|
|||||||
rm -f ns2/db-*
|
rm -f ns2/db-*
|
||||||
rm -f ns2/large.bk
|
rm -f ns2/large.bk
|
||||||
rm -f ns3/example.db.map ns3/dynamic.db.map
|
rm -f ns3/example.db.map ns3/dynamic.db.map
|
||||||
rm -f baseline.txt text.1 text.2 raw.1 raw.2 map.1 map.2
|
rm -f baseline.txt text.1 text.2 raw.1 raw.2 map.1 map.2 map.5 text.5 badmap
|
||||||
|
|
||||||
|
@@ -58,6 +58,16 @@ sourceserial () {
|
|||||||
}' < $1
|
}' < $1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stomp () {
|
||||||
|
perl -e 'open(my $file, "+<", $ARGV[0]);
|
||||||
|
binmode $file;
|
||||||
|
seek($file, $ARGV[1], 0);
|
||||||
|
for (my $i = 0; $i < $ARGV[2]; $i++) {
|
||||||
|
print $file pack('C', $ARGV[3]);
|
||||||
|
}
|
||||||
|
close($file);' $1 $2 $3 $4
|
||||||
|
}
|
||||||
|
|
||||||
restart () {
|
restart () {
|
||||||
sleep 1
|
sleep 1
|
||||||
(cd ..; $PERL start.pl --noclean --restart masterformat ns3)
|
(cd ..; $PERL start.pl --noclean --restart masterformat ns3)
|
||||||
@@ -218,7 +228,28 @@ for i in 0 1 2 3 4 5 6 7 8 9; do
|
|||||||
[ $lret -eq 0 ] && break;
|
[ $lret -eq 0 ] && break;
|
||||||
done
|
done
|
||||||
[ $lret -eq 1 ] && ret=1
|
[ $lret -eq 1 ] && ret=1
|
||||||
|
[ $ret -eq 0 ] || echo "I:failed"
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
# stomp on the file data so it hashes differently.
|
||||||
|
# these are small and subtle changes, so that the resulting file
|
||||||
|
# would appear to be a legitimate map file and would not trigger an
|
||||||
|
# assertion failure if loaded into memory, but should still fail to
|
||||||
|
# load because of a SHA1 hash mismatch.
|
||||||
|
echo "I:checking corrupt map files fail to load (bad node header)"
|
||||||
|
ret=0
|
||||||
|
./named-compilezone -D -f text -F map -o map.5 example.nil baseline.txt > /dev/null
|
||||||
|
cp map.5 badmap
|
||||||
|
stomp badmap 2754 2 99
|
||||||
|
./named-compilezone -D -f map -F text -o text.5 example.nil badmap > /dev/null && ret=1
|
||||||
|
[ $ret -eq 0 ] || echo "I:failed"
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
echo "I:checking corrupt map files fail to load (bad node data)"
|
||||||
|
ret=0
|
||||||
|
cp map.5 badmap
|
||||||
|
stomp badmap 2897 5 127
|
||||||
|
./named-compilezone -D -f map -F text -o text.5 example.nil badmap > /dev/null && ret=1
|
||||||
[ $ret -eq 0 ] || echo "I:failed"
|
[ $ret -eq 0 ] || echo "I:failed"
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include <isc/lang.h>
|
#include <isc/lang.h>
|
||||||
#include <isc/magic.h>
|
#include <isc/magic.h>
|
||||||
#include <isc/refcount.h>
|
#include <isc/refcount.h>
|
||||||
|
#include <isc/sha1.h>
|
||||||
|
|
||||||
#include <dns/types.h>
|
#include <dns/types.h>
|
||||||
|
|
||||||
@@ -152,7 +153,10 @@ typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node,
|
|||||||
|
|
||||||
typedef isc_result_t (*dns_rbtdatawriter_t)(FILE *file,
|
typedef isc_result_t (*dns_rbtdatawriter_t)(FILE *file,
|
||||||
unsigned char *data,
|
unsigned char *data,
|
||||||
isc_uint32_t version);
|
isc_uint32_t version,
|
||||||
|
isc_sha1_t *sha1);
|
||||||
|
|
||||||
|
typedef void (*dns_rbtdatafixer_t)(dns_rbtnode_t *rbtnode, isc_sha1_t *sha1);
|
||||||
|
|
||||||
/*****
|
/*****
|
||||||
***** Chain Info
|
***** Chain Info
|
||||||
@@ -705,7 +709,7 @@ isc_result_t
|
|||||||
dns_rbt_deserialize_tree(void *base_address, off_t header_offset,
|
dns_rbt_deserialize_tree(void *base_address, off_t header_offset,
|
||||||
isc_mem_t *mctx,
|
isc_mem_t *mctx,
|
||||||
void (*deleter)(void *, void *), void *deleter_arg,
|
void (*deleter)(void *, void *), void *deleter_arg,
|
||||||
void (*data_fixer)(dns_rbtnode_t *),
|
dns_rbtdatafixer_t datafixer,
|
||||||
dns_rbtnode_t **originp, dns_rbt_t **rbtp);
|
dns_rbtnode_t **originp, dns_rbt_t **rbtp);
|
||||||
/*%<
|
/*%<
|
||||||
* Read a RBT structure and its data from a file.
|
* Read a RBT structure and its data from a file.
|
||||||
|
@@ -2193,7 +2193,7 @@ openfile_map(dns_loadctx_t *lctx, const char *master_file) {
|
|||||||
*/
|
*/
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
load_map(dns_loadctx_t *lctx) {
|
load_map(dns_loadctx_t *lctx) {
|
||||||
isc_result_t result;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
dns_rdatacallbacks_t *callbacks;
|
dns_rdatacallbacks_t *callbacks;
|
||||||
|
|
||||||
REQUIRE(DNS_LCTX_VALID(lctx));
|
REQUIRE(DNS_LCTX_VALID(lctx));
|
||||||
@@ -2205,12 +2205,12 @@ load_map(dns_loadctx_t *lctx) {
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
|
|
||||||
(*callbacks->deserialize)(callbacks->deserialize_private,
|
result = (*callbacks->deserialize)
|
||||||
lctx->f,
|
(callbacks->deserialize_private,
|
||||||
sizeof(dns_masterrawheader_t));
|
lctx->f, sizeof(dns_masterrawheader_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
|
168
lib/dns/rbt.c
168
lib/dns/rbt.c
@@ -29,10 +29,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <isc/file.h>
|
#include <isc/file.h>
|
||||||
|
#include <isc/hex.h>
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/refcount.h>
|
#include <isc/refcount.h>
|
||||||
|
#include <isc/sha1.h>
|
||||||
#include <isc/socket.h>
|
#include <isc/socket.h>
|
||||||
#include <isc/stdio.h>
|
#include <isc/stdio.h>
|
||||||
#include <isc/string.h>
|
#include <isc/string.h>
|
||||||
@@ -117,6 +119,7 @@ struct file_header {
|
|||||||
unsigned int bigendian:1; /* big or little endian system */
|
unsigned int bigendian:1; /* big or little endian system */
|
||||||
unsigned int rdataset_fixed:1; /* compiled with --enable-rrset-fixed */
|
unsigned int rdataset_fixed:1; /* compiled with --enable-rrset-fixed */
|
||||||
unsigned int nodecount; /* shadow from rbt structure */
|
unsigned int nodecount; /* shadow from rbt structure */
|
||||||
|
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
|
||||||
char version2[32]; /* repeated; must match version1 */
|
char version2[32]; /* repeated; must match version1 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -143,17 +146,18 @@ static isc_result_t
|
|||||||
dns_rbt_zero_header(FILE *file);
|
dns_rbt_zero_header(FILE *file);
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset);
|
write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
|
||||||
|
unsigned char *digest);
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
||||||
uintptr_t right, uintptr_t down, uintptr_t parent,
|
uintptr_t right, uintptr_t down, uintptr_t parent,
|
||||||
uintptr_t data);
|
uintptr_t data, isc_sha1_t *sha1);
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
|
serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
|
||||||
dns_rbtdatawriter_t datawriter, isc_uint32_t serial,
|
dns_rbtdatawriter_t datawriter, isc_uint32_t serial,
|
||||||
uintptr_t *where);
|
uintptr_t *where, isc_sha1_t *sha1);
|
||||||
/*
|
/*
|
||||||
* The following functions allow you to get the actual address of a pointer
|
* The following functions allow you to get the actual address of a pointer
|
||||||
* without having to use an if statement to check to see if that address is
|
* without having to use an if statement to check to see if that address is
|
||||||
@@ -302,6 +306,20 @@ Name(dns_rbtnode_t *node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void printnodename(dns_rbtnode_t *node);
|
static void printnodename(dns_rbtnode_t *node);
|
||||||
|
|
||||||
|
static void
|
||||||
|
hexdump(const char *desc, unsigned char *data, size_t size) {
|
||||||
|
char hexdump[BUFSIZ];
|
||||||
|
isc_buffer_t b;
|
||||||
|
isc_region_t r;
|
||||||
|
|
||||||
|
isc_buffer_init(&b, hexdump, sizeof(hexdump));
|
||||||
|
r.base = data;
|
||||||
|
r.length = size;
|
||||||
|
isc_hex_totext(&r, 0, "", &b);
|
||||||
|
isc_buffer_putuint8(&b, 0);
|
||||||
|
fprintf(stderr, "%s: %s\n", desc, hexdump);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline dns_rbtnode_t *
|
static inline dns_rbtnode_t *
|
||||||
@@ -349,7 +367,7 @@ deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp);
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
treefix(dns_rbt_t *rbt, dns_rbtnode_t *n, dns_name_t *name,
|
treefix(dns_rbt_t *rbt, dns_rbtnode_t *n, dns_name_t *name,
|
||||||
void (*data_fixer)(dns_rbtnode_t *));
|
dns_rbtdatafixer_t datafixer, isc_sha1_t *sha1);
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node);
|
deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node);
|
||||||
@@ -393,7 +411,9 @@ dns_rbt_zero_header(FILE *file) {
|
|||||||
* here.
|
* here.
|
||||||
*/
|
*/
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset) {
|
write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
|
||||||
|
unsigned char *digest)
|
||||||
|
{
|
||||||
file_header_t header;
|
file_header_t header;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
long location;
|
long location;
|
||||||
@@ -419,6 +439,8 @@ write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset) {
|
|||||||
|
|
||||||
header.nodecount = rbt->nodecount;
|
header.nodecount = rbt->nodecount;
|
||||||
|
|
||||||
|
memcpy(header.digest, digest, sizeof(header.digest));
|
||||||
|
|
||||||
location = ftell(file);
|
location = ftell(file);
|
||||||
if (location < 0)
|
if (location < 0)
|
||||||
return (ISC_R_FAILURE);
|
return (ISC_R_FAILURE);
|
||||||
@@ -437,13 +459,16 @@ write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset) {
|
|||||||
static isc_result_t
|
static isc_result_t
|
||||||
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
||||||
uintptr_t right, uintptr_t down, uintptr_t parent,
|
uintptr_t right, uintptr_t down, uintptr_t parent,
|
||||||
uintptr_t data)
|
uintptr_t data, isc_sha1_t *sha1)
|
||||||
{
|
{
|
||||||
dns_rbtnode_t temp_node;
|
dns_rbtnode_t temp_node;
|
||||||
long file_position;
|
long file_position;
|
||||||
unsigned char *node_data;
|
unsigned char *node_data;
|
||||||
size_t datasize;
|
size_t datasize;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
#ifdef DEBUG
|
||||||
|
dns_name_t nodename;
|
||||||
|
#endif
|
||||||
|
|
||||||
INSIST(node != NULL);
|
INSIST(node != NULL);
|
||||||
|
|
||||||
@@ -494,9 +519,23 @@ serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
|||||||
|
|
||||||
CHECK(isc_stdio_write(&temp_node, 1, sizeof(dns_rbtnode_t),
|
CHECK(isc_stdio_write(&temp_node, 1, sizeof(dns_rbtnode_t),
|
||||||
file, NULL));
|
file, NULL));
|
||||||
|
|
||||||
CHECK(isc_stdio_write(node_data, 1, datasize, file, NULL));
|
CHECK(isc_stdio_write(node_data, 1, datasize, file, NULL));
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
dns_name_init(&nodename, NULL);
|
||||||
|
NODENAME(node, &nodename);
|
||||||
|
fprintf(stderr, "serialize ");
|
||||||
|
dns_name_print(&nodename, stderr);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
hexdump("node header", (unsigned char*) &temp_node,
|
||||||
|
sizeof(dns_rbtnode_t));
|
||||||
|
hexdump("node data", node_data, datasize);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
isc_sha1_update(sha1, (const isc_uint8_t *) &temp_node,
|
||||||
|
sizeof(dns_rbtnode_t));
|
||||||
|
isc_sha1_update(sha1, (const isc_uint8_t *) node_data, datasize);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
@@ -504,7 +543,7 @@ serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
|
|||||||
static isc_result_t
|
static isc_result_t
|
||||||
serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
|
serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
|
||||||
dns_rbtdatawriter_t datawriter, isc_uint32_t serial,
|
dns_rbtdatawriter_t datawriter, isc_uint32_t serial,
|
||||||
uintptr_t *where)
|
uintptr_t *where, isc_sha1_t *sha1)
|
||||||
{
|
{
|
||||||
uintptr_t left = 0, right = 0, down = 0, data = 0;
|
uintptr_t left = 0, right = 0, down = 0, data = 0;
|
||||||
long location = 0;
|
long location = 0;
|
||||||
@@ -517,7 +556,7 @@ serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reserve space for current node */
|
/* Reserve space for current node. */
|
||||||
location = ftell(file);
|
location = ftell(file);
|
||||||
if (location < 0)
|
if (location < 0)
|
||||||
return (ISC_R_FAILURE);
|
return (ISC_R_FAILURE);
|
||||||
@@ -530,13 +569,18 @@ serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
|
|||||||
offset_adjust = dns_rbt_serialize_align(location + NODE_SIZE(node));
|
offset_adjust = dns_rbt_serialize_align(location + NODE_SIZE(node));
|
||||||
CHECK(isc_stdio_seek(file, offset_adjust, SEEK_SET));
|
CHECK(isc_stdio_seek(file, offset_adjust, SEEK_SET));
|
||||||
|
|
||||||
/* Serialize the rest of the tree */
|
/*
|
||||||
|
* Serialize the rest of the tree.
|
||||||
|
*
|
||||||
|
* WARNING: A change in the order (from left, right, down)
|
||||||
|
* will break the way the sha1 hash is computed.
|
||||||
|
*/
|
||||||
CHECK(serialize_nodes(file, getleft(node, NULL), location,
|
CHECK(serialize_nodes(file, getleft(node, NULL), location,
|
||||||
datawriter, serial, &left));
|
datawriter, serial, &left, sha1));
|
||||||
CHECK(serialize_nodes(file, getright(node, NULL), location,
|
CHECK(serialize_nodes(file, getright(node, NULL), location,
|
||||||
datawriter, serial, &right));
|
datawriter, serial, &right, sha1));
|
||||||
CHECK(serialize_nodes(file, getdown(node, NULL), location,
|
CHECK(serialize_nodes(file, getdown(node, NULL), location,
|
||||||
datawriter, serial, &down));
|
datawriter, serial, &down, sha1));
|
||||||
|
|
||||||
if (node->data != NULL) {
|
if (node->data != NULL) {
|
||||||
long ret;
|
long ret;
|
||||||
@@ -553,14 +597,15 @@ serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
|
|||||||
return (ISC_R_FAILURE);
|
return (ISC_R_FAILURE);
|
||||||
data = ret;
|
data = ret;
|
||||||
|
|
||||||
datawriter(file, node->data, serial);
|
datawriter(file, node->data, serial, sha1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Seek back to reserved space */
|
/* Seek back to reserved space. */
|
||||||
CHECK(isc_stdio_seek(file, location, SEEK_SET));
|
CHECK(isc_stdio_seek(file, location, SEEK_SET));
|
||||||
|
|
||||||
/* Serialize the current node */
|
/* Serialize the current node. */
|
||||||
CHECK(serialize_node(file, node, left, right, down, parent, data));
|
CHECK(serialize_node(file, node, left, right, down, parent, data,
|
||||||
|
sha1));
|
||||||
|
|
||||||
/* Ensure we are always at the end of the file. */
|
/* Ensure we are always at the end of the file. */
|
||||||
CHECK(isc_stdio_seek(file, 0, SEEK_END));
|
CHECK(isc_stdio_seek(file, 0, SEEK_END));
|
||||||
@@ -589,11 +634,15 @@ dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
|
|||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
long header_position, node_position, end_position;
|
long header_position, node_position, end_position;
|
||||||
|
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
|
||||||
|
isc_sha1_t sha1;
|
||||||
|
|
||||||
REQUIRE(file != NULL);
|
REQUIRE(file != NULL);
|
||||||
|
|
||||||
CHECK(isc_file_isplainfilefd(fileno(file)));
|
CHECK(isc_file_isplainfilefd(fileno(file)));
|
||||||
|
|
||||||
|
isc_sha1_init(&sha1);
|
||||||
|
|
||||||
header_position = ftell(file);
|
header_position = ftell(file);
|
||||||
if (header_position < 0)
|
if (header_position < 0)
|
||||||
return (ISC_R_FAILURE);
|
return (ISC_R_FAILURE);
|
||||||
@@ -606,7 +655,8 @@ dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
|
|||||||
if (node_position < 0)
|
if (node_position < 0)
|
||||||
return (ISC_R_FAILURE);
|
return (ISC_R_FAILURE);
|
||||||
|
|
||||||
CHECK(serialize_nodes(file, rbt->root, 0, datawriter, serial, NULL));
|
CHECK(serialize_nodes(file, rbt->root, 0, datawriter, serial, NULL,
|
||||||
|
&sha1));
|
||||||
end_position = ftell(file);
|
end_position = ftell(file);
|
||||||
if (end_position < 0)
|
if (end_position < 0)
|
||||||
return (ISC_R_FAILURE);
|
return (ISC_R_FAILURE);
|
||||||
@@ -617,9 +667,14 @@ dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isc_sha1_final(&sha1, digest);
|
||||||
|
#ifdef DEBUG
|
||||||
|
hexdump("serializing digest", digest, sizeof(digest));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Serialize header */
|
/* Serialize header */
|
||||||
CHECK(isc_stdio_seek(file, header_position, SEEK_SET));
|
CHECK(isc_stdio_seek(file, header_position, SEEK_SET));
|
||||||
CHECK(write_header(file, rbt, HEADER_LENGTH));
|
CHECK(write_header(file, rbt, HEADER_LENGTH, digest));
|
||||||
|
|
||||||
/* Ensure we are always at the end of the file. */
|
/* Ensure we are always at the end of the file. */
|
||||||
CHECK(isc_stdio_seek(file, 0, SEEK_END));
|
CHECK(isc_stdio_seek(file, 0, SEEK_END));
|
||||||
@@ -631,11 +686,14 @@ dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
treefix(dns_rbt_t *rbt, dns_rbtnode_t *n, dns_name_t *name,
|
treefix(dns_rbt_t *rbt, dns_rbtnode_t *n, dns_name_t *name,
|
||||||
void (*data_fixer)(dns_rbtnode_t *))
|
dns_rbtdatafixer_t datafixer, isc_sha1_t *sha1)
|
||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_fixedname_t fixed;
|
dns_fixedname_t fixed;
|
||||||
dns_name_t nodename, *fullname;
|
dns_name_t nodename, *fullname;
|
||||||
|
unsigned char *node_data;
|
||||||
|
dns_rbtnode_t header;
|
||||||
|
size_t datasize;
|
||||||
|
|
||||||
if (n == NULL)
|
if (n == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -652,6 +710,9 @@ treefix(dns_rbt_t *rbt, dns_rbtnode_t *n, dns_name_t *name,
|
|||||||
/* XXX: we need to catch errors better than this */
|
/* XXX: we need to catch errors better than this */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* memorize header contents prior to fixup */
|
||||||
|
memcpy(&header, n, sizeof(header));
|
||||||
|
|
||||||
INSIST(!n->parent_is_relative || n->parent != NULL);
|
INSIST(!n->parent_is_relative || n->parent != NULL);
|
||||||
INSIST(!n->right_is_relative || n->right != NULL);
|
INSIST(!n->right_is_relative || n->right != NULL);
|
||||||
INSIST(!n->left_is_relative || n->left != NULL);
|
INSIST(!n->left_is_relative || n->left != NULL);
|
||||||
@@ -675,15 +736,32 @@ treefix(dns_rbt_t *rbt, dns_rbtnode_t *n, dns_name_t *name,
|
|||||||
|
|
||||||
hash_node(rbt, n, fullname);
|
hash_node(rbt, n, fullname);
|
||||||
|
|
||||||
if (data_fixer != NULL && n->data != NULL)
|
/* a change in the order (from left, right, down) will break hashing*/
|
||||||
data_fixer(n);
|
|
||||||
|
|
||||||
if (n->right != NULL)
|
|
||||||
treefix(rbt, n->right, name, data_fixer);
|
|
||||||
if (n->left != NULL)
|
if (n->left != NULL)
|
||||||
treefix(rbt, n->left, name, data_fixer);
|
treefix(rbt, n->left, name, datafixer, sha1);
|
||||||
|
if (n->right != NULL)
|
||||||
|
treefix(rbt, n->right, name, datafixer, sha1);
|
||||||
if (n->down != NULL)
|
if (n->down != NULL)
|
||||||
treefix(rbt, n->down, fullname, data_fixer);
|
treefix(rbt, n->down, fullname, datafixer, sha1);
|
||||||
|
|
||||||
|
if (datafixer != NULL && n->data != NULL)
|
||||||
|
datafixer(n, sha1);
|
||||||
|
|
||||||
|
node_data = (unsigned char *) n + sizeof(dns_rbtnode_t);
|
||||||
|
datasize = NODE_SIZE(n) - sizeof(dns_rbtnode_t);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "deserialize ");
|
||||||
|
dns_name_print(&nodename, stderr);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
hexdump("node header", (unsigned char *) &header,
|
||||||
|
sizeof(dns_rbtnode_t));
|
||||||
|
hexdump("node data", node_data, datasize);
|
||||||
|
#endif
|
||||||
|
isc_sha1_update(sha1, (const isc_uint8_t *) &header,
|
||||||
|
sizeof(dns_rbtnode_t));
|
||||||
|
isc_sha1_update(sha1, (const isc_uint8_t *) node_data,
|
||||||
|
datasize);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
@@ -691,14 +769,18 @@ dns_rbt_deserialize_tree(void *base_address, off_t header_offset,
|
|||||||
isc_mem_t *mctx,
|
isc_mem_t *mctx,
|
||||||
void (*deleter)(void *, void *),
|
void (*deleter)(void *, void *),
|
||||||
void *deleter_arg,
|
void *deleter_arg,
|
||||||
void (*data_fixer)(dns_rbtnode_t *),
|
dns_rbtdatafixer_t datafixer,
|
||||||
dns_rbtnode_t **originp, dns_rbt_t **rbtp)
|
dns_rbtnode_t **originp, dns_rbt_t **rbtp)
|
||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
file_header_t *header;
|
file_header_t *header;
|
||||||
|
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
|
||||||
|
isc_sha1_t sha1;
|
||||||
|
|
||||||
REQUIRE(originp == NULL || *originp == NULL);
|
REQUIRE(originp == NULL || *originp == NULL);
|
||||||
|
|
||||||
|
isc_sha1_init(&sha1);
|
||||||
|
|
||||||
result = dns_rbt_create(mctx, deleter, deleter_arg, rbtp);
|
result = dns_rbt_create(mctx, deleter, deleter_arg, rbtp);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
@@ -729,7 +811,15 @@ dns_rbt_deserialize_tree(void *base_address, off_t header_offset,
|
|||||||
(*rbtp)->root = (dns_rbtnode_t *)((char *)base_address +
|
(*rbtp)->root = (dns_rbtnode_t *)((char *)base_address +
|
||||||
header_offset + header->first_node_offset);
|
header_offset + header->first_node_offset);
|
||||||
(*rbtp)->nodecount = header->nodecount;
|
(*rbtp)->nodecount = header->nodecount;
|
||||||
treefix(*rbtp, (*rbtp)->root, dns_rootname, data_fixer);
|
treefix(*rbtp, (*rbtp)->root, dns_rootname, datafixer, &sha1);
|
||||||
|
|
||||||
|
isc_sha1_final(&sha1, digest);
|
||||||
|
#ifdef DEBUG
|
||||||
|
hexdump("deserializing digest", digest, sizeof(digest));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (memcmp(header->digest, digest, sizeof(digest)) != 0)
|
||||||
|
return (ISC_R_INVALIDFILE);
|
||||||
|
|
||||||
if (originp != NULL)
|
if (originp != NULL)
|
||||||
*originp = (*rbtp)->root;
|
*originp = (*rbtp)->root;
|
||||||
@@ -749,7 +839,6 @@ dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *, void *),
|
|||||||
#endif
|
#endif
|
||||||
dns_rbt_t *rbt;
|
dns_rbt_t *rbt;
|
||||||
|
|
||||||
|
|
||||||
REQUIRE(mctx != NULL);
|
REQUIRE(mctx != NULL);
|
||||||
REQUIRE(rbtp != NULL && *rbtp == NULL);
|
REQUIRE(rbtp != NULL && *rbtp == NULL);
|
||||||
REQUIRE(deleter == NULL ? deleter_arg == NULL : 1);
|
REQUIRE(deleter == NULL ? deleter_arg == NULL : 1);
|
||||||
@@ -820,13 +909,17 @@ dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum) {
|
|||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
dns_rbt_nodecount(dns_rbt_t *rbt) {
|
dns_rbt_nodecount(dns_rbt_t *rbt) {
|
||||||
|
|
||||||
REQUIRE(VALID_RBT(rbt));
|
REQUIRE(VALID_RBT(rbt));
|
||||||
|
|
||||||
return (rbt->nodecount);
|
return (rbt->nodecount);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
dns_rbt_hashsize(dns_rbt_t *rbt) {
|
dns_rbt_hashsize(dns_rbt_t *rbt) {
|
||||||
|
|
||||||
REQUIRE(VALID_RBT(rbt));
|
REQUIRE(VALID_RBT(rbt));
|
||||||
|
|
||||||
return (rbt->hashsize);
|
return (rbt->hashsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2552,6 +2645,7 @@ deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) {
|
|||||||
static isc_result_t
|
static isc_result_t
|
||||||
deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) {
|
deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) {
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
REQUIRE(VALID_RBT(rbt));
|
REQUIRE(VALID_RBT(rbt));
|
||||||
|
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
@@ -2607,6 +2701,7 @@ static void
|
|||||||
deletetreeflat(dns_rbt_t *rbt, unsigned int quantum, dns_rbtnode_t **nodep) {
|
deletetreeflat(dns_rbt_t *rbt, unsigned int quantum, dns_rbtnode_t **nodep) {
|
||||||
dns_rbtnode_t *parent;
|
dns_rbtnode_t *parent;
|
||||||
dns_rbtnode_t *node = *nodep;
|
dns_rbtnode_t *node = *nodep;
|
||||||
|
|
||||||
REQUIRE(VALID_RBT(rbt));
|
REQUIRE(VALID_RBT(rbt));
|
||||||
|
|
||||||
again:
|
again:
|
||||||
@@ -2760,6 +2855,7 @@ dns_rbt_printtree(dns_rbtnode_t *root, dns_rbtnode_t *parent,
|
|||||||
|
|
||||||
void
|
void
|
||||||
dns_rbt_printall(dns_rbt_t *rbt, void (*data_printer)(FILE *, void *)) {
|
dns_rbt_printall(dns_rbt_t *rbt, void (*data_printer)(FILE *, void *)) {
|
||||||
|
|
||||||
REQUIRE(VALID_RBT(rbt));
|
REQUIRE(VALID_RBT(rbt));
|
||||||
|
|
||||||
dns_rbt_printtree(rbt->root, NULL, 0, "root", data_printer);
|
dns_rbt_printtree(rbt->root, NULL, 0, "root", data_printer);
|
||||||
@@ -2771,12 +2867,12 @@ dns_rbt_printall(dns_rbt_t *rbt, void (*data_printer)(FILE *, void *)) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
dns_rbtnodechain_init(dns_rbtnodechain_t *chain, isc_mem_t *mctx) {
|
dns_rbtnodechain_init(dns_rbtnodechain_t *chain, isc_mem_t *mctx) {
|
||||||
/*
|
|
||||||
* Initialize 'chain'.
|
|
||||||
*/
|
|
||||||
|
|
||||||
REQUIRE(chain != NULL);
|
REQUIRE(chain != NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize 'chain'.
|
||||||
|
*/
|
||||||
chain->mctx = mctx;
|
chain->mctx = mctx;
|
||||||
chain->end = NULL;
|
chain->end = NULL;
|
||||||
chain->level_count = 0;
|
chain->level_count = 0;
|
||||||
@@ -3217,13 +3313,13 @@ dns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt,
|
|||||||
|
|
||||||
void
|
void
|
||||||
dns_rbtnodechain_reset(dns_rbtnodechain_t *chain) {
|
dns_rbtnodechain_reset(dns_rbtnodechain_t *chain) {
|
||||||
|
|
||||||
|
REQUIRE(VALID_CHAIN(chain));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free any dynamic storage associated with 'chain', and then
|
* Free any dynamic storage associated with 'chain', and then
|
||||||
* reinitialize 'chain'.
|
* reinitialize 'chain'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
REQUIRE(VALID_CHAIN(chain));
|
|
||||||
|
|
||||||
chain->end = NULL;
|
chain->end = NULL;
|
||||||
chain->level_count = 0;
|
chain->level_count = 0;
|
||||||
chain->level_matches = 0;
|
chain->level_matches = 0;
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include <isc/event.h>
|
#include <isc/event.h>
|
||||||
#include <isc/heap.h>
|
#include <isc/heap.h>
|
||||||
#include <isc/file.h>
|
#include <isc/file.h>
|
||||||
|
#include <isc/hex.h>
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
#include <isc/mutex.h>
|
#include <isc/mutex.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
@@ -728,6 +729,25 @@ static unsigned int init_count;
|
|||||||
* For zone databases the node for the origin of the zone MUST NOT be deleted.
|
* For zone databases the node for the origin of the zone MUST NOT be deleted.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debugging routines
|
||||||
|
*/
|
||||||
|
#ifdef DEBUG
|
||||||
|
static void
|
||||||
|
hexdump(const char *desc, unsigned char *data, size_t size) {
|
||||||
|
char hexdump[BUFSIZ];
|
||||||
|
isc_buffer_t b;
|
||||||
|
isc_region_t r;
|
||||||
|
|
||||||
|
isc_buffer_init(&b, hexdump, sizeof(hexdump));
|
||||||
|
r.base = data;
|
||||||
|
r.length = size;
|
||||||
|
isc_hex_totext(&r, 0, "", &b);
|
||||||
|
isc_buffer_putuint8(&b, 0);
|
||||||
|
fprintf(stderr, "%s: %s\n", desc, hexdump);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DB Routines
|
* DB Routines
|
||||||
@@ -6976,7 +6996,7 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fix_data(dns_rbtnode_t *rbtnode) {
|
rbt_datafixer(dns_rbtnode_t *rbtnode, isc_sha1_t *sha1) {
|
||||||
rdatasetheader_t *header;
|
rdatasetheader_t *header;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
size_t size;
|
size_t size;
|
||||||
@@ -6984,12 +7004,18 @@ fix_data(dns_rbtnode_t *rbtnode) {
|
|||||||
REQUIRE(rbtnode != NULL);
|
REQUIRE(rbtnode != NULL);
|
||||||
|
|
||||||
for (header = rbtnode->data; header != NULL; header = header->next) {
|
for (header = rbtnode->data; header != NULL; header = header->next) {
|
||||||
|
p = (unsigned char *) header;
|
||||||
|
size = dns_rdataslab_size(p, sizeof(*header));
|
||||||
|
isc_sha1_update(sha1, p, size);
|
||||||
|
#ifdef DEBUG
|
||||||
|
hexdump("hashing header", p, sizeof(rdatasetheader_t));
|
||||||
|
hexdump("hashing slab", p + sizeof(rdatasetheader_t),
|
||||||
|
size - sizeof(rdatasetheader_t));
|
||||||
|
#endif
|
||||||
header->serial = 1;
|
header->serial = 1;
|
||||||
header->is_mmapped = 1;
|
header->is_mmapped = 1;
|
||||||
header->node = rbtnode;
|
header->node = rbtnode;
|
||||||
header->node_is_relative = 0;
|
header->node_is_relative = 0;
|
||||||
p = (unsigned char *) header;
|
|
||||||
size = dns_rdataslab_size(p, sizeof(*header));
|
|
||||||
if (header->next != NULL) {
|
if (header->next != NULL) {
|
||||||
header->next = (rdatasetheader_t *)(p + size);
|
header->next = (rdatasetheader_t *)(p + size);
|
||||||
header->next_is_relative = 0;
|
header->next_is_relative = 0;
|
||||||
@@ -7002,6 +7028,7 @@ fix_data(dns_rbtnode_t *rbtnode) {
|
|||||||
*/
|
*/
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
deserialize(void *arg, FILE *f, off_t offset) {
|
deserialize(void *arg, FILE *f, off_t offset) {
|
||||||
|
isc_result_t result;
|
||||||
rbtdb_load_t *loadctx = arg;
|
rbtdb_load_t *loadctx = arg;
|
||||||
dns_rbtdb_t *rbtdb = loadctx->rbtdb;
|
dns_rbtdb_t *rbtdb = loadctx->rbtdb;
|
||||||
rbtdb_file_header_t *header;
|
rbtdb_file_header_t *header;
|
||||||
@@ -7039,11 +7066,12 @@ deserialize(void *arg, FILE *f, off_t offset) {
|
|||||||
rbtdb->origin_node = NULL;
|
rbtdb->origin_node = NULL;
|
||||||
|
|
||||||
if (header->tree != 0) {
|
if (header->tree != 0) {
|
||||||
dns_rbt_deserialize_tree(base, header->tree,
|
result = dns_rbt_deserialize_tree(base, header->tree,
|
||||||
rbtdb->common.mctx, delete_callback,
|
rbtdb->common.mctx,
|
||||||
rbtdb, fix_data,
|
delete_callback,
|
||||||
&rbtdb->origin_node,
|
rbtdb, rbt_datafixer,
|
||||||
&temporary_rbt);
|
&rbtdb->origin_node,
|
||||||
|
&temporary_rbt);
|
||||||
if (temporary_rbt != NULL) {
|
if (temporary_rbt != NULL) {
|
||||||
dns_rbt_destroy(&rbtdb->tree);
|
dns_rbt_destroy(&rbtdb->tree);
|
||||||
rbtdb->tree = temporary_rbt;
|
rbtdb->tree = temporary_rbt;
|
||||||
@@ -7052,28 +7080,38 @@ deserialize(void *arg, FILE *f, off_t offset) {
|
|||||||
rbtdb->origin_node =
|
rbtdb->origin_node =
|
||||||
(dns_rbtnode_t *)(header->tree + base + 1024);
|
(dns_rbtnode_t *)(header->tree + base + 1024);
|
||||||
}
|
}
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header->nsec != 0) {
|
if (header->nsec != 0) {
|
||||||
dns_rbt_deserialize_tree(base, header->nsec,
|
result = dns_rbt_deserialize_tree(base, header->nsec,
|
||||||
rbtdb->common.mctx, delete_callback,
|
rbtdb->common.mctx,
|
||||||
rbtdb, fix_data, NULL, &temporary_rbt);
|
delete_callback,
|
||||||
|
rbtdb, rbt_datafixer,
|
||||||
|
NULL, &temporary_rbt);
|
||||||
if (temporary_rbt != NULL) {
|
if (temporary_rbt != NULL) {
|
||||||
dns_rbt_destroy(&rbtdb->nsec);
|
dns_rbt_destroy(&rbtdb->nsec);
|
||||||
rbtdb->nsec = temporary_rbt;
|
rbtdb->nsec = temporary_rbt;
|
||||||
temporary_rbt = NULL;
|
temporary_rbt = NULL;
|
||||||
}
|
}
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header->nsec3 != 0) {
|
if (header->nsec3 != 0) {
|
||||||
dns_rbt_deserialize_tree(base, header->nsec3,
|
result = dns_rbt_deserialize_tree(base, header->nsec3,
|
||||||
rbtdb->common.mctx, delete_callback,
|
rbtdb->common.mctx,
|
||||||
rbtdb, fix_data, NULL, &temporary_rbt);
|
delete_callback,
|
||||||
|
rbtdb, rbt_datafixer,
|
||||||
|
NULL, &temporary_rbt);
|
||||||
if (temporary_rbt != NULL) {
|
if (temporary_rbt != NULL) {
|
||||||
dns_rbt_destroy(&rbtdb->nsec3);
|
dns_rbt_destroy(&rbtdb->nsec3);
|
||||||
rbtdb->nsec3 = temporary_rbt;
|
rbtdb->nsec3 = temporary_rbt;
|
||||||
temporary_rbt = NULL;
|
temporary_rbt = NULL;
|
||||||
}
|
}
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
@@ -7151,7 +7189,7 @@ endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|||||||
* If there's a KEY rdataset at the zone origin containing a
|
* If there's a KEY rdataset at the zone origin containing a
|
||||||
* zone key, we consider the zone secure.
|
* zone key, we consider the zone secure.
|
||||||
*/
|
*/
|
||||||
if (! IS_CACHE(rbtdb))
|
if (! IS_CACHE(rbtdb) && rbtdb->origin_node != NULL)
|
||||||
iszonesecure(db, rbtdb->current_version, rbtdb->origin_node);
|
iszonesecure(db, rbtdb->current_version, rbtdb->origin_node);
|
||||||
|
|
||||||
callbacks->add = NULL;
|
callbacks->add = NULL;
|
||||||
@@ -7169,7 +7207,8 @@ endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|||||||
* by the void *data pointer in the dns_rbtnode
|
* by the void *data pointer in the dns_rbtnode
|
||||||
*/
|
*/
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
rbt_datawriter(FILE *rbtfile, unsigned char *data, isc_uint32_t serial) {
|
rbt_datawriter(FILE *rbtfile, unsigned char *data, isc_uint32_t serial,
|
||||||
|
isc_sha1_t *sha1) {
|
||||||
rdatasetheader_t newheader;
|
rdatasetheader_t newheader;
|
||||||
rdatasetheader_t *header = (rdatasetheader_t *) data, *next;
|
rdatasetheader_t *header = (rdatasetheader_t *) data, *next;
|
||||||
size_t where, size;
|
size_t where, size;
|
||||||
@@ -7210,12 +7249,22 @@ rbt_datawriter(FILE *rbtfile, unsigned char *data, isc_uint32_t serial) {
|
|||||||
newheader.next_is_relative = 1;
|
newheader.next_is_relative = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
hexdump("writing header", (unsigned char *) &newheader,
|
||||||
|
sizeof(rdatasetheader_t));
|
||||||
|
hexdump("writing slab", p + sizeof(rdatasetheader_t),
|
||||||
|
size - sizeof(rdatasetheader_t));
|
||||||
|
#endif
|
||||||
|
isc_sha1_update(sha1, (unsigned char *) &newheader,
|
||||||
|
sizeof(rdatasetheader_t));
|
||||||
result = isc_stdio_write(&newheader,
|
result = isc_stdio_write(&newheader,
|
||||||
sizeof(rdatasetheader_t), 1,
|
sizeof(rdatasetheader_t), 1,
|
||||||
rbtfile, NULL);
|
rbtfile, NULL);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
|
|
||||||
|
isc_sha1_update(sha1, p + sizeof(rdatasetheader_t),
|
||||||
|
size - sizeof(rdatasetheader_t));
|
||||||
result = isc_stdio_write(p + sizeof(rdatasetheader_t),
|
result = isc_stdio_write(p + sizeof(rdatasetheader_t),
|
||||||
size - sizeof(rdatasetheader_t), 1, rbtfile, NULL);
|
size - sizeof(rdatasetheader_t), 1, rbtfile, NULL);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
|
Reference in New Issue
Block a user