index.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. var types = require('./types')
  2. var rcodes = require('./rcodes')
  3. var opcodes = require('./opcodes')
  4. var ip = require('ip')
  5. var Buffer = require('safe-buffer').Buffer
  6. var QUERY_FLAG = 0
  7. var RESPONSE_FLAG = 1 << 15
  8. var FLUSH_MASK = 1 << 15
  9. var NOT_FLUSH_MASK = ~FLUSH_MASK
  10. var QU_MASK = 1 << 15
  11. var NOT_QU_MASK = ~QU_MASK
  12. var name = exports.txt = exports.name = {}
  13. name.encode = function (str, buf, offset) {
  14. if (!buf) buf = Buffer.alloc(name.encodingLength(str))
  15. if (!offset) offset = 0
  16. var oldOffset = offset
  17. // strip leading and trailing .
  18. var n = str.replace(/^\.|\.$/gm, '')
  19. if (n.length) {
  20. var list = n.split('.')
  21. for (var i = 0; i < list.length; i++) {
  22. var len = buf.write(list[i], offset + 1)
  23. buf[offset] = len
  24. offset += len + 1
  25. }
  26. }
  27. buf[offset++] = 0
  28. name.encode.bytes = offset - oldOffset
  29. return buf
  30. }
  31. name.encode.bytes = 0
  32. name.decode = function (buf, offset) {
  33. if (!offset) offset = 0
  34. var list = []
  35. var oldOffset = offset
  36. var len = buf[offset++]
  37. if (len === 0) {
  38. name.decode.bytes = 1
  39. return '.'
  40. }
  41. if (len >= 0xc0) {
  42. var res = name.decode(buf, buf.readUInt16BE(offset - 1) - 0xc000)
  43. name.decode.bytes = 2
  44. return res
  45. }
  46. while (len) {
  47. if (len >= 0xc0) {
  48. list.push(name.decode(buf, buf.readUInt16BE(offset - 1) - 0xc000))
  49. offset++
  50. break
  51. }
  52. list.push(buf.toString('utf-8', offset, offset + len))
  53. offset += len
  54. len = buf[offset++]
  55. }
  56. name.decode.bytes = offset - oldOffset
  57. return list.join('.')
  58. }
  59. name.decode.bytes = 0
  60. name.encodingLength = function (n) {
  61. if (n === '.' || n === '..') return 1
  62. return Buffer.byteLength(n.replace(/^\.|\.$/gm, '')) + 2
  63. }
  64. var string = {}
  65. string.encode = function (s, buf, offset) {
  66. if (!buf) buf = Buffer.alloc(string.encodingLength(s))
  67. if (!offset) offset = 0
  68. var len = buf.write(s, offset + 1)
  69. buf[offset] = len
  70. string.encode.bytes = len + 1
  71. return buf
  72. }
  73. string.encode.bytes = 0
  74. string.decode = function (buf, offset) {
  75. if (!offset) offset = 0
  76. var len = buf[offset]
  77. var s = buf.toString('utf-8', offset + 1, offset + 1 + len)
  78. string.decode.bytes = len + 1
  79. return s
  80. }
  81. string.decode.bytes = 0
  82. string.encodingLength = function (s) {
  83. return Buffer.byteLength(s) + 1
  84. }
  85. var header = {}
  86. header.encode = function (h, buf, offset) {
  87. if (!buf) buf = header.encodingLength(h)
  88. if (!offset) offset = 0
  89. var flags = (h.flags || 0) & 32767
  90. var type = h.type === 'response' ? RESPONSE_FLAG : QUERY_FLAG
  91. buf.writeUInt16BE(h.id || 0, offset)
  92. buf.writeUInt16BE(flags | type, offset + 2)
  93. buf.writeUInt16BE(h.questions.length, offset + 4)
  94. buf.writeUInt16BE(h.answers.length, offset + 6)
  95. buf.writeUInt16BE(h.authorities.length, offset + 8)
  96. buf.writeUInt16BE(h.additionals.length, offset + 10)
  97. return buf
  98. }
  99. header.encode.bytes = 12
  100. header.decode = function (buf, offset) {
  101. if (!offset) offset = 0
  102. if (buf.length < 12) throw new Error('Header must be 12 bytes')
  103. var flags = buf.readUInt16BE(offset + 2)
  104. return {
  105. id: buf.readUInt16BE(offset),
  106. type: flags & RESPONSE_FLAG ? 'response' : 'query',
  107. flags: flags & 32767,
  108. flag_qr: ((flags >> 15) & 0x1) === 1,
  109. opcode: opcodes.toString((flags >> 11) & 0xf),
  110. flag_auth: ((flags >> 10) & 0x1) === 1,
  111. flag_trunc: ((flags >> 9) & 0x1) === 1,
  112. flag_rd: ((flags >> 8) & 0x1) === 1,
  113. flag_ra: ((flags >> 7) & 0x1) === 1,
  114. flag_z: ((flags >> 6) & 0x1) === 1,
  115. flag_ad: ((flags >> 5) & 0x1) === 1,
  116. flag_cd: ((flags >> 4) & 0x1) === 1,
  117. rcode: rcodes.toString(flags & 0xf),
  118. questions: new Array(buf.readUInt16BE(offset + 4)),
  119. answers: new Array(buf.readUInt16BE(offset + 6)),
  120. authorities: new Array(buf.readUInt16BE(offset + 8)),
  121. additionals: new Array(buf.readUInt16BE(offset + 10))
  122. }
  123. }
  124. header.decode.bytes = 12
  125. header.encodingLength = function () {
  126. return 12
  127. }
  128. var runknown = exports.unknown = {}
  129. runknown.encode = function (data, buf, offset) {
  130. if (!buf) buf = Buffer.alloc(runknown.encodingLength(data))
  131. if (!offset) offset = 0
  132. buf.writeUInt16BE(data.length, offset)
  133. data.copy(buf, offset + 2)
  134. runknown.encode.bytes = data.length + 2
  135. return buf
  136. }
  137. runknown.encode.bytes = 0
  138. runknown.decode = function (buf, offset) {
  139. if (!offset) offset = 0
  140. var len = buf.readUInt16BE(offset)
  141. var data = buf.slice(offset + 2, offset + 2 + len)
  142. runknown.decode.bytes = len + 2
  143. return data
  144. }
  145. runknown.decode.bytes = 0
  146. runknown.encodingLength = function (data) {
  147. return data.length + 2
  148. }
  149. var rns = exports.ns = {}
  150. rns.encode = function (data, buf, offset) {
  151. if (!buf) buf = Buffer.alloc(rns.encodingLength(data))
  152. if (!offset) offset = 0
  153. name.encode(data, buf, offset + 2)
  154. buf.writeUInt16BE(name.encode.bytes, offset)
  155. rns.encode.bytes = name.encode.bytes + 2
  156. return buf
  157. }
  158. rns.encode.bytes = 0
  159. rns.decode = function (buf, offset) {
  160. if (!offset) offset = 0
  161. var len = buf.readUInt16BE(offset)
  162. var dd = name.decode(buf, offset + 2)
  163. rns.decode.bytes = len + 2
  164. return dd
  165. }
  166. rns.decode.bytes = 0
  167. rns.encodingLength = function (data) {
  168. return name.encodingLength(data) + 2
  169. }
  170. var rsoa = exports.soa = {}
  171. rsoa.encode = function (data, buf, offset) {
  172. if (!buf) buf = Buffer.alloc(rsoa.encodingLength(data))
  173. if (!offset) offset = 0
  174. var oldOffset = offset
  175. offset += 2
  176. name.encode(data.mname, buf, offset)
  177. offset += name.encode.bytes
  178. name.encode(data.rname, buf, offset)
  179. offset += name.encode.bytes
  180. buf.writeUInt32BE(data.serial || 0, offset)
  181. offset += 4
  182. buf.writeUInt32BE(data.refresh || 0, offset)
  183. offset += 4
  184. buf.writeUInt32BE(data.retry || 0, offset)
  185. offset += 4
  186. buf.writeUInt32BE(data.expire || 0, offset)
  187. offset += 4
  188. buf.writeUInt32BE(data.minimum || 0, offset)
  189. offset += 4
  190. buf.writeUInt16BE(offset - oldOffset - 2, oldOffset)
  191. rsoa.encode.bytes = offset - oldOffset
  192. return buf
  193. }
  194. rsoa.encode.bytes = 0
  195. rsoa.decode = function (buf, offset) {
  196. if (!offset) offset = 0
  197. var oldOffset = offset
  198. var data = {}
  199. offset += 2
  200. data.mname = name.decode(buf, offset)
  201. offset += name.decode.bytes
  202. data.rname = name.decode(buf, offset)
  203. offset += name.decode.bytes
  204. data.serial = buf.readUInt32BE(offset)
  205. offset += 4
  206. data.refresh = buf.readUInt32BE(offset)
  207. offset += 4
  208. data.retry = buf.readUInt32BE(offset)
  209. offset += 4
  210. data.expire = buf.readUInt32BE(offset)
  211. offset += 4
  212. data.minimum = buf.readUInt32BE(offset)
  213. offset += 4
  214. rsoa.decode.bytes = offset - oldOffset
  215. return data
  216. }
  217. rsoa.decode.bytes = 0
  218. rsoa.encodingLength = function (data) {
  219. return 22 + name.encodingLength(data.mname) + name.encodingLength(data.rname)
  220. }
  221. var rtxt = exports.txt = exports.null = {}
  222. var rnull = rtxt
  223. rtxt.encode = function (data, buf, offset) {
  224. if (!buf) buf = Buffer.alloc(rtxt.encodingLength(data))
  225. if (!offset) offset = 0
  226. if (typeof data === 'string') data = Buffer.from(data)
  227. if (!data) data = Buffer.alloc(0)
  228. var oldOffset = offset
  229. offset += 2
  230. var len = data.length
  231. data.copy(buf, offset, 0, len)
  232. offset += len
  233. buf.writeUInt16BE(offset - oldOffset - 2, oldOffset)
  234. rtxt.encode.bytes = offset - oldOffset
  235. return buf
  236. }
  237. rtxt.encode.bytes = 0
  238. rtxt.decode = function (buf, offset) {
  239. if (!offset) offset = 0
  240. var oldOffset = offset
  241. var len = buf.readUInt16BE(offset)
  242. offset += 2
  243. var data = buf.slice(offset, offset + len)
  244. offset += len
  245. rtxt.decode.bytes = offset - oldOffset
  246. return data
  247. }
  248. rtxt.decode.bytes = 0
  249. rtxt.encodingLength = function (data) {
  250. if (!data) return 2
  251. return (Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data)) + 2
  252. }
  253. var rhinfo = exports.hinfo = {}
  254. rhinfo.encode = function (data, buf, offset) {
  255. if (!buf) buf = Buffer.alloc(rhinfo.encodingLength(data))
  256. if (!offset) offset = 0
  257. var oldOffset = offset
  258. offset += 2
  259. string.encode(data.cpu, buf, offset)
  260. offset += string.encode.bytes
  261. string.encode(data.os, buf, offset)
  262. offset += string.encode.bytes
  263. buf.writeUInt16BE(offset - oldOffset - 2, oldOffset)
  264. rhinfo.encode.bytes = offset - oldOffset
  265. return buf
  266. }
  267. rhinfo.encode.bytes = 0
  268. rhinfo.decode = function (buf, offset) {
  269. if (!offset) offset = 0
  270. var oldOffset = offset
  271. var data = {}
  272. offset += 2
  273. data.cpu = string.decode(buf, offset)
  274. offset += string.decode.bytes
  275. data.os = string.decode(buf, offset)
  276. offset += string.decode.bytes
  277. rhinfo.decode.bytes = offset - oldOffset
  278. return data
  279. }
  280. rhinfo.decode.bytes = 0
  281. rhinfo.encodingLength = function (data) {
  282. return string.encodingLength(data.cpu) + string.encodingLength(data.os) + 2
  283. }
  284. var rptr = exports.ptr = {}
  285. var rcname = exports.cname = rptr
  286. var rdname = exports.dname = rptr
  287. rptr.encode = function (data, buf, offset) {
  288. if (!buf) buf = Buffer.alloc(rptr.encodingLength(data))
  289. if (!offset) offset = 0
  290. name.encode(data, buf, offset + 2)
  291. buf.writeUInt16BE(name.encode.bytes, offset)
  292. rptr.encode.bytes = name.encode.bytes + 2
  293. return buf
  294. }
  295. rptr.encode.bytes = 0
  296. rptr.decode = function (buf, offset) {
  297. if (!offset) offset = 0
  298. var data = name.decode(buf, offset + 2)
  299. rptr.decode.bytes = name.decode.bytes + 2
  300. return data
  301. }
  302. rptr.decode.bytes = 0
  303. rptr.encodingLength = function (data) {
  304. return name.encodingLength(data) + 2
  305. }
  306. var rsrv = exports.srv = {}
  307. rsrv.encode = function (data, buf, offset) {
  308. if (!buf) buf = Buffer.alloc(rsrv.encodingLength(data))
  309. if (!offset) offset = 0
  310. buf.writeUInt16BE(data.priority || 0, offset + 2)
  311. buf.writeUInt16BE(data.weight || 0, offset + 4)
  312. buf.writeUInt16BE(data.port || 0, offset + 6)
  313. name.encode(data.target, buf, offset + 8)
  314. var len = name.encode.bytes + 6
  315. buf.writeUInt16BE(len, offset)
  316. rsrv.encode.bytes = len + 2
  317. return buf
  318. }
  319. rsrv.encode.bytes = 0
  320. rsrv.decode = function (buf, offset) {
  321. if (!offset) offset = 0
  322. var len = buf.readUInt16BE(offset)
  323. var data = {}
  324. data.priority = buf.readUInt16BE(offset + 2)
  325. data.weight = buf.readUInt16BE(offset + 4)
  326. data.port = buf.readUInt16BE(offset + 6)
  327. data.target = name.decode(buf, offset + 8)
  328. rsrv.decode.bytes = len + 2
  329. return data
  330. }
  331. rsrv.decode.bytes = 0
  332. rsrv.encodingLength = function (data) {
  333. return 8 + name.encodingLength(data.target)
  334. }
  335. var rcaa = exports.caa = {}
  336. rcaa.ISSUER_CRITICAL = 1 << 7
  337. rcaa.encode = function (data, buf, offset) {
  338. var len = rcaa.encodingLength(data)
  339. if (!buf) buf = Buffer.alloc(rcaa.encodingLength(data))
  340. if (!offset) offset = 0
  341. if (data.issuerCritical) {
  342. data.flags = rcaa.ISSUER_CRITICAL
  343. }
  344. buf.writeUInt16BE(len - 2, offset)
  345. offset += 2
  346. buf.writeUInt8(data.flags || 0, offset)
  347. offset += 1
  348. string.encode(data.tag, buf, offset)
  349. offset += string.encode.bytes
  350. buf.write(data.value, offset)
  351. offset += Buffer.byteLength(data.value)
  352. rcaa.encode.bytes = len
  353. return buf
  354. }
  355. rcaa.encode.bytes = 0
  356. rcaa.decode = function (buf, offset) {
  357. if (!offset) offset = 0
  358. var len = buf.readUInt16BE(offset)
  359. offset += 2
  360. var oldOffset = offset
  361. var data = {}
  362. data.flags = buf.readUInt8(offset)
  363. offset += 1
  364. data.tag = string.decode(buf, offset)
  365. offset += string.decode.bytes
  366. data.value = buf.toString('utf-8', offset, oldOffset + len)
  367. data.issuerCritical = !!(data.flags & rcaa.ISSUER_CRITICAL)
  368. rcaa.decode.bytes = len + 2
  369. return data
  370. }
  371. rcaa.decode.bytes = 0
  372. rcaa.encodingLength = function (data) {
  373. return string.encodingLength(data.tag) + string.encodingLength(data.value) + 2
  374. }
  375. var ra = exports.a = {}
  376. ra.encode = function (host, buf, offset) {
  377. if (!buf) buf = Buffer.alloc(ra.encodingLength(host))
  378. if (!offset) offset = 0
  379. buf.writeUInt16BE(4, offset)
  380. offset += 2
  381. ip.toBuffer(host, buf, offset)
  382. ra.encode.bytes = 6
  383. return buf
  384. }
  385. ra.encode.bytes = 0
  386. ra.decode = function (buf, offset) {
  387. if (!offset) offset = 0
  388. offset += 2
  389. var host = ip.toString(buf, offset, 4)
  390. ra.decode.bytes = 6
  391. return host
  392. }
  393. ra.decode.bytes = 0
  394. ra.encodingLength = function () {
  395. return 6
  396. }
  397. var raaaa = exports.aaaa = {}
  398. raaaa.encode = function (host, buf, offset) {
  399. if (!buf) buf = Buffer.alloc(raaaa.encodingLength(host))
  400. if (!offset) offset = 0
  401. buf.writeUInt16BE(16, offset)
  402. offset += 2
  403. ip.toBuffer(host, buf, offset)
  404. raaaa.encode.bytes = 18
  405. return buf
  406. }
  407. raaaa.encode.bytes = 0
  408. raaaa.decode = function (buf, offset) {
  409. if (!offset) offset = 0
  410. offset += 2
  411. var host = ip.toString(buf, offset, 16)
  412. raaaa.decode.bytes = 18
  413. return host
  414. }
  415. raaaa.decode.bytes = 0
  416. raaaa.encodingLength = function () {
  417. return 18
  418. }
  419. var renc = exports.record = function (type) {
  420. switch (type.toUpperCase()) {
  421. case 'A': return ra
  422. case 'PTR': return rptr
  423. case 'CNAME': return rcname
  424. case 'DNAME': return rdname
  425. case 'TXT': return rtxt
  426. case 'NULL': return rnull
  427. case 'AAAA': return raaaa
  428. case 'SRV': return rsrv
  429. case 'HINFO': return rhinfo
  430. case 'CAA': return rcaa
  431. case 'NS': return rns
  432. case 'SOA': return rsoa
  433. }
  434. return runknown
  435. }
  436. var answer = exports.answer = {}
  437. answer.encode = function (a, buf, offset) {
  438. if (!buf) buf = Buffer.alloc(answer.encodingLength(a))
  439. if (!offset) offset = 0
  440. var oldOffset = offset
  441. name.encode(a.name, buf, offset)
  442. offset += name.encode.bytes
  443. buf.writeUInt16BE(types.toType(a.type), offset)
  444. var klass = a.class === undefined ? 1 : a.class
  445. if (a.flush) klass |= FLUSH_MASK // the 1st bit of the class is the flush bit
  446. buf.writeUInt16BE(klass, offset + 2)
  447. buf.writeUInt32BE(a.ttl || 0, offset + 4)
  448. var enc = renc(a.type)
  449. enc.encode(a.data, buf, offset + 8)
  450. offset += 8 + enc.encode.bytes
  451. answer.encode.bytes = offset - oldOffset
  452. return buf
  453. }
  454. answer.encode.bytes = 0
  455. answer.decode = function (buf, offset) {
  456. if (!offset) offset = 0
  457. var a = {}
  458. var oldOffset = offset
  459. a.name = name.decode(buf, offset)
  460. offset += name.decode.bytes
  461. a.type = types.toString(buf.readUInt16BE(offset))
  462. a.class = buf.readUInt16BE(offset + 2)
  463. a.ttl = buf.readUInt32BE(offset + 4)
  464. a.flush = !!(a.class & FLUSH_MASK)
  465. if (a.flush) a.class &= NOT_FLUSH_MASK
  466. var enc = renc(a.type)
  467. a.data = enc.decode(buf, offset + 8)
  468. offset += 8 + enc.decode.bytes
  469. answer.decode.bytes = offset - oldOffset
  470. return a
  471. }
  472. answer.decode.bytes = 0
  473. answer.encodingLength = function (a) {
  474. return name.encodingLength(a.name) + 8 + renc(a.type).encodingLength(a.data)
  475. }
  476. var question = exports.question = {}
  477. question.encode = function (q, buf, offset) {
  478. if (!buf) buf = Buffer.alloc(question.encodingLength(q))
  479. if (!offset) offset = 0
  480. var oldOffset = offset
  481. name.encode(q.name, buf, offset)
  482. offset += name.encode.bytes
  483. buf.writeUInt16BE(types.toType(q.type), offset)
  484. offset += 2
  485. buf.writeUInt16BE(q.class === undefined ? 1 : q.class, offset)
  486. offset += 2
  487. question.encode.bytes = offset - oldOffset
  488. return q
  489. }
  490. question.encode.bytes = 0
  491. question.decode = function (buf, offset) {
  492. if (!offset) offset = 0
  493. var oldOffset = offset
  494. var q = {}
  495. q.name = name.decode(buf, offset)
  496. offset += name.decode.bytes
  497. q.type = types.toString(buf.readUInt16BE(offset))
  498. offset += 2
  499. q.class = buf.readUInt16BE(offset)
  500. offset += 2
  501. var qu = !!(q.class & QU_MASK)
  502. if (qu) q.class &= NOT_QU_MASK
  503. question.decode.bytes = offset - oldOffset
  504. return q
  505. }
  506. question.decode.bytes = 0
  507. question.encodingLength = function (q) {
  508. return name.encodingLength(q.name) + 4
  509. }
  510. exports.AUTHORITATIVE_ANSWER = 1 << 10
  511. exports.TRUNCATED_RESPONSE = 1 << 9
  512. exports.RECURSION_DESIRED = 1 << 8
  513. exports.RECURSION_AVAILABLE = 1 << 7
  514. exports.AUTHENTIC_DATA = 1 << 5
  515. exports.CHECKING_DISABLED = 1 << 4
  516. exports.encode = function (result, buf, offset) {
  517. var allocing = !buf
  518. if (allocing) buf = Buffer.alloc(exports.encodingLength(result))
  519. if (!offset) offset = 0
  520. var oldOffset = offset
  521. if (!result.questions) result.questions = []
  522. if (!result.answers) result.answers = []
  523. if (!result.authorities) result.authorities = []
  524. if (!result.additionals) result.additionals = []
  525. header.encode(result, buf, offset)
  526. offset += header.encode.bytes
  527. offset = encodeList(result.questions, question, buf, offset)
  528. offset = encodeList(result.answers, answer, buf, offset)
  529. offset = encodeList(result.authorities, answer, buf, offset)
  530. offset = encodeList(result.additionals, answer, buf, offset)
  531. exports.encode.bytes = offset - oldOffset
  532. // just a quick sanity check
  533. if (allocing && exports.encode.bytes !== buf.length) {
  534. return buf.slice(0, exports.encode.bytes)
  535. }
  536. return buf
  537. }
  538. exports.encode.bytes = 0
  539. exports.decode = function (buf, offset) {
  540. if (!offset) offset = 0
  541. var oldOffset = offset
  542. var result = header.decode(buf, offset)
  543. offset += header.decode.bytes
  544. offset = decodeList(result.questions, question, buf, offset)
  545. offset = decodeList(result.answers, answer, buf, offset)
  546. offset = decodeList(result.authorities, answer, buf, offset)
  547. offset = decodeList(result.additionals, answer, buf, offset)
  548. exports.decode.bytes = offset - oldOffset
  549. return result
  550. }
  551. exports.decode.bytes = 0
  552. exports.encodingLength = function (result) {
  553. return header.encodingLength(result) +
  554. encodingLengthList(result.questions || [], question) +
  555. encodingLengthList(result.answers || [], answer) +
  556. encodingLengthList(result.authorities || [], answer) +
  557. encodingLengthList(result.additionals || [], answer)
  558. }
  559. function encodingLengthList (list, enc) {
  560. var len = 0
  561. for (var i = 0; i < list.length; i++) len += enc.encodingLength(list[i])
  562. return len
  563. }
  564. function encodeList (list, enc, buf, offset) {
  565. for (var i = 0; i < list.length; i++) {
  566. enc.encode(list[i], buf, offset)
  567. offset += enc.encode.bytes
  568. }
  569. return offset
  570. }
  571. function decodeList (list, enc, buf, offset) {
  572. for (var i = 0; i < list.length; i++) {
  573. list[i] = enc.decode(buf, offset)
  574. offset += enc.decode.bytes
  575. }
  576. return offset
  577. }