forked from LittleChest/dns-packet
Add encoder for stream transports (TCP/TLS). (#23)
* Add encoder for stream transports (TCP/TLS). Fixes #16. * Add README text and return null on short buffer.
This commit is contained in:
parent
600d4acd90
commit
7904e095e9
@ -9,7 +9,7 @@ npm install dns-packet
|
|||||||
|
|
||||||
[](https://travis-ci.org/mafintosh/dns-packet)
|
[](https://travis-ci.org/mafintosh/dns-packet)
|
||||||
|
|
||||||
## Usage
|
## UDP Usage
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
var packet = require('dns-packet')
|
var packet = require('dns-packet')
|
||||||
@ -35,6 +35,10 @@ socket.on('message', function (message) {
|
|||||||
socket.send(buf, 0, buf.length, 53, '8.8.8.8')
|
socket.send(buf, 0, buf.length, 53, '8.8.8.8')
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TCP Usage
|
||||||
|
|
||||||
|
While DNS has traditionally been used over a datagram transport, it is increasingly being carried over TCP for larger responses commonly including DNSSEC responses and TCP/TLS for privacy reasons.
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
#### `var buf = packets.encode(packet, [buf], [offset])`
|
#### `var buf = packets.encode(packet, [buf], [offset])`
|
||||||
|
|||||||
30
example_tcp.js
Normal file
30
example_tcp.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
const packet = require('./')
|
||||||
|
const net = require('net')
|
||||||
|
|
||||||
|
const buf = packet.streamEncode({
|
||||||
|
type: 'query',
|
||||||
|
id: 0xdead,
|
||||||
|
flags: packet.RECURSION_DESIRED,
|
||||||
|
questions: [{
|
||||||
|
type: 'A',
|
||||||
|
name: 'google.com'
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
const client = new net.Socket()
|
||||||
|
client.connect(53, '8.8.8.8', function () {
|
||||||
|
console.log('Connected')
|
||||||
|
client.write(buf)
|
||||||
|
})
|
||||||
|
|
||||||
|
client.on('data', function (data) {
|
||||||
|
console.log('Received response')
|
||||||
|
console.log(packet.streamDecode(data))
|
||||||
|
client.destroy() // kill client after server's response
|
||||||
|
})
|
||||||
|
|
||||||
|
client.on('close', function () {
|
||||||
|
console.log('Connection closed')
|
||||||
|
})
|
||||||
23
index.js
23
index.js
@ -811,6 +811,29 @@ exports.encodingLength = function (result) {
|
|||||||
encodingLengthList(result.additionals || [], answer)
|
encodingLengthList(result.additionals || [], answer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.streamEncode = function (result) {
|
||||||
|
const len = exports.encodingLength(result)
|
||||||
|
const buf = Buffer.allocUnsafe(len + 2)
|
||||||
|
exports.encode(result, buf, 2)
|
||||||
|
buf.writeUInt16BE(len, 0)
|
||||||
|
exports.streamEncode.bytes = len + 2
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.streamEncode.bytes = 0
|
||||||
|
|
||||||
|
exports.streamDecode = function (buf) {
|
||||||
|
const len = buf.readUInt16BE(0)
|
||||||
|
if (buf.length < len + 2) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const result = exports.decode(buf, 2)
|
||||||
|
exports.streamDecode.bytes = exports.decode.bytes + 2
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.streamDecode.bytes = 0
|
||||||
|
|
||||||
function encodingLengthList (list, enc) {
|
function encodingLengthList (list, enc) {
|
||||||
let len = 0
|
let len = 0
|
||||||
for (let i = 0; i < list.length; i++) len += enc.encodingLength(list[i])
|
for (let i = 0; i < list.length; i++) len += enc.encodingLength(list[i])
|
||||||
|
|||||||
27
test.js
27
test.js
@ -289,6 +289,33 @@ tape('name_encoding', function (t) {
|
|||||||
t.end()
|
t.end()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
tape('stream', function (t) {
|
||||||
|
const val = {
|
||||||
|
type: 'query',
|
||||||
|
id: 45632,
|
||||||
|
flags: 0x8480,
|
||||||
|
answers: [{
|
||||||
|
type: 'A',
|
||||||
|
name: 'test2.example.net',
|
||||||
|
data: '198.51.100.1'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
const buf = packet.streamEncode(val)
|
||||||
|
const val2 = packet.streamDecode(buf)
|
||||||
|
|
||||||
|
t.same(buf.length, packet.streamEncode.bytes, 'streamEncode.bytes was set correctly')
|
||||||
|
t.same(packet.streamDecode.bytes, packet.streamEncode.bytes, 'streamDecode.bytes was set correctly')
|
||||||
|
t.ok(compare(t, val2.type, val.type), 'streamDecoded type match')
|
||||||
|
t.ok(compare(t, val2.id, val.id), 'streamDecoded id match')
|
||||||
|
t.ok(parseInt(val2.flags) === parseInt(val.flags & 0x7FFF), 'streamDecoded flags match')
|
||||||
|
const answer = val.answers[0]
|
||||||
|
const answer2 = val2.answers[0]
|
||||||
|
t.ok(compare(t, answer.type, answer2.type), 'streamDecoded RR type match')
|
||||||
|
t.ok(compare(t, answer.name, answer2.name), 'streamDecoded RR name match')
|
||||||
|
t.ok(compare(t, answer.data, answer2.data), 'streamDecoded RR rdata match')
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
|
||||||
function testEncoder (t, rpacket, val) {
|
function testEncoder (t, rpacket, val) {
|
||||||
const buf = rpacket.encode(val)
|
const buf = rpacket.encode(val)
|
||||||
const val2 = rpacket.decode(buf)
|
const val2 = rpacket.decode(buf)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user