diff --git a/README.md b/README.md index c86d088..1477ead 100644 --- a/README.md +++ b/README.md @@ -366,6 +366,22 @@ The options `PADDING`, `CLIENT_SUBNET`, `TCP_KEEPALIVE` and `KEY_TAG` support en } ``` +#### `NAPTR` + +``` js +{ + data: + { + order: 100, + preference: 10, + flags: 's', + services: 'SIP+D2U', + regexp: '!^.*$!sip:customer-service@example.com!', + replacement: '_sip._udp.example.com' + } +} +``` + When encoding, scalar values are converted to an array and strings are converted to UTF-8 encoded Buffers. When decoding, the return value will always be an array of Buffer. If you need another record type, open an issue and we'll try to add it. diff --git a/index.js b/index.js index 53fd70c..cc45e80 100644 --- a/index.js +++ b/index.js @@ -1353,6 +1353,62 @@ rsshfp.encodingLength = function (record) { return 4 + Buffer.from(record.fingerprint, 'hex').byteLength } +const rnaptr = exports.naptr = {} + +rnaptr.encode = function (data, buf, offset) { + if (!buf) buf = Buffer.alloc(rnaptr.encodingLength(data)) + if (!offset) offset = 0 + const oldOffset = offset + offset += 2 + buf.writeUInt16BE(data.order || 0, offset) + offset += 2 + buf.writeUInt16BE(data.preference || 0, offset) + offset += 2 + string.encode(data.flags, buf, offset) + offset += string.encode.bytes + string.encode(data.services, buf, offset) + offset += string.encode.bytes + string.encode(data.regexp, buf, offset) + offset += string.encode.bytes + name.encode(data.replacement, buf, offset) + offset += name.encode.bytes + rnaptr.encode.bytes = offset - oldOffset + buf.writeUInt16BE(rnaptr.encode.bytes - 2, oldOffset) + return buf +} + +rnaptr.encode.bytes = 0 + +rnaptr.decode = function (buf, offset) { + if (!offset) offset = 0 + const oldOffset = offset + const data = {} + offset += 2 + data.order = buf.readUInt16BE(offset) + offset += 2 + data.preference = buf.readUInt16BE(offset) + offset += 2 + data.flags = string.decode(buf, offset) + offset += string.decode.bytes + data.services = string.decode(buf, offset) + offset += string.decode.bytes + data.regexp = string.decode(buf, offset) + offset += string.decode.bytes + data.replacement = name.decode(buf, offset) + offset += name.decode.bytes + rnaptr.decode.bytes = offset - oldOffset + return data +} + +rnaptr.decode.bytes = 0 + +rnaptr.encodingLength = function (data) { + return string.encodingLength(data.flags) + + string.encodingLength(data.services) + + string.encodingLength(data.regexp) + + name.encodingLength(data.replacement) + 6 +} + const renc = exports.record = function (type) { switch (type.toUpperCase()) { case 'A': return ra @@ -1376,6 +1432,7 @@ const renc = exports.record = function (type) { case 'NSEC3': return rnsec3 case 'SSHFP': return rsshfp case 'DS': return rds + case 'NAPTR': return rnaptr } return runknown } diff --git a/test.js b/test.js index 4848d06..927b56f 100644 --- a/test.js +++ b/test.js @@ -556,6 +556,18 @@ tape('ds', function (t) { t.end() }) +tape('naptr', function (t) { + testEncoder(t, packet.naptr, { + order: 1, + preference: 1, + flags: 'S', + services: 'SIP+D2T', + regexp: '!^.*$!sip:customer-service@xuexample.com!', + replacement: '_sip._udp.xuexample.com' + }) + t.end() +}) + tape('unpack', function (t) { const buf = Buffer.from([ 0x00, 0x79,