Comparing version 1.0.1 to 1.1.0
71
index.js
"use strict"; | ||
const dnsSocket = require("dns-socket"); | ||
const util = require("util"); | ||
const noop = () => {}; | ||
const resolve = ({name, socket, server, port}) => { | ||
return new Promise(resolve => { | ||
socket.query({questions: [{name, type: "CAA"}]}, port, server, (_, res) => { | ||
if (res && res.answers && res.answers.length && res.answers[0].data) { | ||
resolve(res.answers.map(a => a.data)); | ||
} else { | ||
resolve(null); | ||
} | ||
}); | ||
}); | ||
// map answer to {type: [data]} | ||
function parseAnswers(res) { | ||
const types = {}; | ||
if (!res || !res.answers) return null; | ||
for (const answer of res.answers) { | ||
if (!answer.type || !answer.data) return; | ||
if (!types[answer.type]) types[answer.type] = []; | ||
types[answer.type].push(answer.data); | ||
} | ||
return Object.keys(types).length ? types : null; | ||
} | ||
const resolve = async ({name, socket, server, port}) => { | ||
const query = util.promisify(socket.query.bind(socket)); | ||
const [cname, dname, caa] = await Promise.all([ | ||
query({questions: [{name, type: "CNAME"}]}, port, server).then(parseAnswers).catch(noop), | ||
query({questions: [{name, type: "DNAME"}]}, port, server).then(parseAnswers).catch(noop), | ||
query({questions: [{name, type: "CAA"}]}, port, server).then(parseAnswers).catch(noop), | ||
]); | ||
// If CAA(X) is not empty, R(X) = CAA (X) | ||
let alias; | ||
if (caa && caa.CAA && caa.CAA.length) { | ||
return caa.CAA; | ||
} else if (cname && cname.CNAME.length) { | ||
alias = cname.CNAME[0]; | ||
} else if (dname && dname.DNAME.length) { | ||
alias = dname.DNAME[0]; | ||
} | ||
// If ALIAS(X) is not null, and R(A(X)) is not empty, then R(X) = R(A(X)) | ||
if (alias) { | ||
const acaa = await query({questions: [{name: alias, type: "CAA"}]}, port, server).then(parseAnswers).catch(noop); | ||
if (acaa && acaa.CAA && acaa.CAA.length) { | ||
return acaa.CAA; | ||
} | ||
} | ||
// If X is not a top-level domain, then R(X) = R(P(X)) | ||
if (name.split(".").length > 1) { | ||
const parent = name.split(".").splice(1).join("."); | ||
return await resolve({name: parent, socket, server, port}); | ||
} else { | ||
return []; | ||
} | ||
}; | ||
@@ -39,15 +77,6 @@ | ||
// climb up the DNS name tree | ||
let caa; | ||
const socket = dnsSocket(); | ||
while (name && !caa) { | ||
try { | ||
caa = await resolve({name, socket, server, port}); | ||
} catch (err) {} | ||
name = name.split(".").splice(1).join("."); | ||
} | ||
const caa = await resolve({name, socket, server, port}); | ||
socket.destroy(); | ||
return caa || null; | ||
return caa || []; | ||
}; |
{ | ||
"name": "caa", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "rfc6844-conform CAA record lookup", | ||
@@ -5,0 +5,0 @@ "author": "silverwind <me@silverwind.io>", |
5301
69