It's a Christmas miracle! refactored and got CNAME in one shot - W00T!

This commit is contained in:
AJ ONeal 2017-01-28 15:15:27 -07:00
parent 11484f70ba
commit 88093062a2
3 changed files with 96 additions and 78 deletions

View File

@ -1,18 +1,13 @@
(function (exports) {
'use strict';
// TODO. Not yet implemented
// A CNAME reocord maps a single alias or nickname to the real or
// Canonical name which may lie outside the current zone.
// Canonical simply means the expected or real name.
exports.DNS_TYPE_CNAME = function (rdata) {
var unpackLabels = exports.DNS_UNPACK_LABELS || require('./dns.unpack-labels.js').DNS_UNPACK_LABELS;
exports.DNS_TYPE_CNAME = function (ab, packet, record) {
return unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name;
};
}('undefined' !== typeof window ? window : exports));

61
dns.unpack-labels.js Normal file
View File

@ -0,0 +1,61 @@
(function (exports) {
'use strict';
// unpack labels with 0x20 compression pointer support
// ui8 is the ArrayBuffer of the entire packet
// ptr is the current index of the packet
// q = { byteLength: 0, cpcount: 0, labels: [], name: '' }
exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) {
if (q.cpcount > 25) {
throw new Error("compression pointer loop detected (over 25 pointers seems like a loop)");
}
var total = ptr;
var i;
var len;
var label = [];
do {
label.length = 0;
len = ui8[total];
if (0xc0 === len) {
var cpptr = ui8[total + 1];
// we're not coming back!
ptr = cpptr;
q.cpcount += 1;
q.byteLength += 2; // cp and len
return exports.DNS_UNPACK_LABELS(ui8, ptr, q);
}
//str.length = 0; // fast empty array
if (ui8.byteLength - total < len) {
throw new Error(
"Expected a string of length " + len
+ " but packet itself has " + (ui8.byteLength - total) + " bytes remaining"
);
}
for (i = 0; i < len; i += 1) {
total += 1;
// TODO check url-allowable characters
label.push(String.fromCharCode(ui8[total]));
}
if (label.length) {
q.labels.push(label.join(''));
}
total += 1;
//console.log('total', total, ui8[total], String.fromCharCode(ui8[total]));
} while (len);
//str.pop(); // remove trailing '.'
q.name = q.labels.join('.');
if (0 === q.cpcount) {
q.byteLength = total - ptr;
}
return q;
};
}('undefined' !== typeof window ? window : exports));

View File

@ -1,3 +1,4 @@
;(function (exports) {
'use strict';
var pdns = module.exports;
@ -29,70 +30,7 @@ pdns.unpackHeader = function (i) {
return header;
};
pdns.unpackQname = function (ui8, ptr, q) {
return pdns._unpackQname(ui8, ptr, q || {
name: ''
, type: 0
, typeName: ''
, class: 0
, className: ''
, byteLength: 0
, labels: []
, cpcount: 0
});
};
pdns._unpackQname = function (ui8, ptr, q) {
if (q.cpcount > 25) {
throw new Error("compression pointer loop detected (over 25 pointers seems like a loop)");
}
var total = ptr;
var i;
var len;
var label = [];
do {
label.length = 0;
len = ui8[total];
if (0xc0 === len) {
var cpptr = ui8[total + 1];
// we're not coming back!
ptr = cpptr;
q.cpcount += 1;
q.byteLength += 2; // cp and len
return pdns.unpackQname(ui8, ptr, q);
}
//str.length = 0; // fast empty array
if (ui8.byteLength - total < len) {
throw new Error(
"Expected a string of length " + len
+ " but packet itself has " + (ui8.byteLength - total) + " bytes remaining"
);
}
for (i = 0; i < len; i += 1) {
total += 1;
// TODO check url-allowable characters
label.push(String.fromCharCode(ui8[total]));
}
if (label.length) {
q.labels.push(label.join(''));
}
total += 1;
//console.log('total', total, ui8[total], String.fromCharCode(ui8[total]));
} while (len);
//str.pop(); // remove trailing '.'
q.name = q.labels.join('.');
if (0 === q.cpcount) {
q.byteLength = total - ptr;
}
return q;
};
pdns._unpackLabels = exports.DNS_UNPACK_LABELS || require('./dns.unpack-labels.js').DNS_UNPACK_LABELS;
pdns.unpack = function (ab) {
if (ab.buffer) {
@ -133,7 +71,16 @@ pdns.unpack = function (ab) {
// TODO move to pdns.unpackQuestion to make testable
function unpackQuestion(ab, dv, ui8, total) {
var ototal = total;
var q = pdns.unpackQname(ui8, total);
var q = pdns._unpackLabels(ui8, total, {
name: ''
, type: 0
, typeName: ''
, class: 0
, className: ''
, byteLength: 0
, labels: []
, cpcount: 0
});
//console.log('unpackQuestion QNAME:');
//console.log(q);
total += q.byteLength;
@ -167,7 +114,20 @@ pdns.unpack = function (ab) {
function unpackAnswer(ab, dv, ui8, total) {
var ototal = total;
var q = pdns.unpackQname(ui8, total);
var q = pdns._unpackLabels(ui8, total, {
name: ''
, type: 0
, typeName: ''
, class: 0
, className: ''
, byteLength: 0
, labels: []
, cpcount: 0
, rdstart: 0
, rdata: 0
, rdlength: 0
});
//console.log('unpackAnswer QNAME:');
//console.log(q);
total += q.byteLength;
@ -196,6 +156,7 @@ pdns.unpack = function (ab) {
// TODO actually parse RDATA
q.rdstart = total;
q.rdata = new Uint8Array(ab).slice(total, total + q.rdlength);
console.log('q.rdata', q.rdata.byteLength, 'bytes:');
console.log(q.rdata);
@ -250,3 +211,4 @@ pdns.unpack = function (ab) {
return header;
};
pdns.unpackRdata = require('./dns.rdata.parse.js').DNS_RDATA_PARSE;
}('undefined' !== typeof window ? window : exports));