From 77f314e0f7527f27ea5664849d3d319d101296d0 Mon Sep 17 00:00:00 2001 From: Matthew Zipkin Date: Fri, 8 Jan 2021 15:48:17 -0500 Subject: [PATCH 1/2] node: rpc dumpzone Co-authored-by: James Stevens Co-authored-by: Mark Tyneway --- lib/node/rpc.js | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/lib/node/rpc.js b/lib/node/rpc.js index 9668d61d2..07ff8c704 100644 --- a/lib/node/rpc.js +++ b/lib/node/rpc.js @@ -6,6 +6,10 @@ 'use strict'; +const constants = require('bns/lib/constants'); +const {types} = constants; +const fs = require('fs'); +const bns = require('bns'); const assert = require('bsert'); const bweb = require('bweb'); const {Lock} = require('bmutex'); @@ -246,6 +250,7 @@ class RPC extends RPCBase { this.add('validateresource', this.validateResource); this.add('resetrootcache', this.resetRootCache); + this.add('dumpzone', this.dumpzone); // Compat // this.add('getnameinfo', this.getNameInfo); @@ -2533,6 +2538,68 @@ class RPC extends RPCBase { return null; } + async dumpzone(args, help) { + if (help || args.length !== 1) + throw new RPCError(errs.MISC_ERROR, 'dumpzone '); + + const valid = new Validator(args); + const filename = valid.str(0, null); + if (filename == null) + throw new RPCError(errs.MISC_ERROR, 'dumpzone '); + + const tmp = filename + '~'; + this.logger.debug(`dumping root zone to file: ${filename}`); + + let fd = null; + let fileErr = null; + fd = fs.createWriteStream(tmp, { flags: 'a+' }); + fd.on('error', (err) => { + fd.end(); + fd = null; + fileErr = err; + }); + + const tree = this.chain.db.tree; + const iter = tree.iterator(true); + + let count = 0; + while ((await iter.next()) && (fd != null)) { + count++; + if (count % 10000 === 0) + this.logger.debug('dumpzone names processed: %d', count); + + if (fd == null) + break; + + const {value} = iter; + const ns = NameState.decode(value); + + if (ns.data.length <= 0) + continue; + + const fqdn = bns.util.fqdn(ns.name.toString('ascii')); + const resource = Resource.decode(ns.data); + const zone = resource.toZone(fqdn); + for (const record of zone) { + if (fd == null) + break; + + if (record.type !== types.RRSIG) + fd.write(record.toString() + '\n'); + } + } + + if (fd == null) + return fileErr; + + fd.end(); + fs.renameSync(tmp, filename); + + this.logger.debug('root zone dump complete. Total names: %d', count); + + return filename; + } + /* * Helpers */ From e80b835b3a05308a71fac7b5a8647573280ad085 Mon Sep 17 00:00:00 2001 From: Matthew Zipkin Date: Fri, 26 Feb 2021 07:46:11 -0500 Subject: [PATCH 2/2] resource: decode synth in toZone() --- lib/dns/resource.js | 8 ++++---- test/data/hns.zone | 12 ++++++++++++ test/resource-test.js | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 test/data/hns.zone diff --git a/lib/dns/resource.js b/lib/dns/resource.js index 93bfdd84b..38fe91d92 100644 --- a/lib/dns/resource.js +++ b/lib/dns/resource.js @@ -258,12 +258,12 @@ class Resource extends Struct { for (const record of this.records) { switch (record.type) { case hsTypes.GLUE4: - case hsTypes.GLUE6: - case hsTypes.SYNTH4: - case hsTypes.SYNTH6: { + case hsTypes.GLUE6: { if (!util.isSubdomain(name, record.ns)) continue; - + } + case hsTypes.SYNTH4: + case hsTypes.SYNTH6: { zone.push(record.toGlue(record.ns, this.ttl)); break; } diff --git a/test/data/hns.zone b/test/data/hns.zone new file mode 100644 index 000000000..00687eef5 --- /dev/null +++ b/test/data/hns.zone @@ -0,0 +1,12 @@ +hns. 21600 IN DS 57355 8 2 95A57C3BAB7849DBCDDF7C72ADA71A88146B141110318CA5BE672057 E865C3E2 ; alg = RSASHA256 ; hash = SHA256 +hns. 21600 IN NS ns1.hns. +hns. 21600 IN NS ns2.hns. +hns. 21600 IN NS ns3.some-other-domain. +hns. 21600 IN NS ns4.hns. +hns. 21600 IN NS _fs0000g._synth. +hns. 21600 IN NS _00000000000000000000000008._synth. +hns. 21600 IN TXT "hello world" +ns2.hns. 21600 IN A 127.0.0.1 +ns4.hns. 21600 IN AAAA ::1 +_fs0000g._synth. 21600 IN A 127.0.0.2 +_00000000000000000000000008._synth. 21600 IN AAAA ::2 diff --git a/test/resource-test.js b/test/resource-test.js index c5593c13f..7ab3eabf2 100644 --- a/test/resource-test.js +++ b/test/resource-test.js @@ -1,6 +1,8 @@ 'use strict'; const assert = require('bsert'); +const fs = require('fs'); +const Path = require ('path'); const {wire} = require('bns'); const {Resource} = require('../lib/dns/resource'); const {types} = wire; @@ -58,6 +60,23 @@ describe('Resource', function() { assert.deepStrictEqual(res1.toJSON(), res2.toJSON()); }); + it('should dump zone', async () => { + const expected = await fs.readFileSync( + Path.join(__dirname, 'data', 'hns.zone'), + 'ascii' + ); + + const res = Resource.fromJSON(json); + const zone = res.toZone('hns.'); + let file = ''; + for (const record of zone) { + if (record.type !== types.RRSIG) + file += record.toString() + '\n'; + } + + assert.deepStrictEqual(file, expected); + }); + it('should synthesize a referral', () => { const res = Resource.fromJSON(json); const msg = res.toDNS('hns.', types.MX);