index.js 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629
  1. 'use strict'
  2. const Buffer = require('buffer').Buffer
  3. const types = require('./types')
  4. const rcodes = require('./rcodes')
  5. const opcodes = require('./opcodes')
  6. const classes = require('./classes')
  7. const optioncodes = require('./optioncodes')
  8. const ip = require('@leichtgewicht/ip-codec')
  9. const QUERY_FLAG = 0
  10. const RESPONSE_FLAG = 1 << 15
  11. const FLUSH_MASK = 1 << 15
  12. const NOT_FLUSH_MASK = ~FLUSH_MASK
  13. const QU_MASK = 1 << 15
  14. const NOT_QU_MASK = ~QU_MASK
  15. const name = exports.name = {}
  16. name.encode = function (str, buf, offset) {
  17. if (!buf) buf = Buffer.alloc(name.encodingLength(str))
  18. if (!offset) offset = 0
  19. const oldOffset = offset
  20. // strip leading and trailing .
  21. const n = str.replace(/^\.|\.$/gm, '')
  22. if (n.length) {
  23. const list = n.split('.')
  24. for (let i = 0; i < list.length; i++) {
  25. const len = buf.write(list[i], offset + 1)
  26. buf[offset] = len
  27. offset += len + 1
  28. }
  29. }
  30. buf[offset++] = 0
  31. name.encode.bytes = offset - oldOffset
  32. return buf
  33. }
  34. name.encode.bytes = 0
  35. name.decode = function (buf, offset) {
  36. if (!offset) offset = 0
  37. const list = []
  38. let oldOffset = offset
  39. let totalLength = 0
  40. let consumedBytes = 0
  41. let jumped = false
  42. while (true) {
  43. if (offset >= buf.length) {
  44. throw new Error('Cannot decode name (buffer overflow)')
  45. }
  46. const len = buf[offset++]
  47. consumedBytes += jumped ? 0 : 1
  48. if (len === 0) {
  49. break
  50. } else if ((len & 0xc0) === 0) {
  51. if (offset + len > buf.length) {
  52. throw new Error('Cannot decode name (buffer overflow)')
  53. }
  54. totalLength += len + 1
  55. if (totalLength > 254) {
  56. throw new Error('Cannot decode name (name too long)')
  57. }
  58. list.push(buf.toString('utf-8', offset, offset + len))
  59. offset += len
  60. consumedBytes += jumped ? 0 : len
  61. } else if ((len & 0xc0) === 0xc0) {
  62. if (offset + 1 > buf.length) {
  63. throw new Error('Cannot decode name (buffer overflow)')
  64. }
  65. const jumpOffset = buf.readUInt16BE(offset - 1) - 0xc000
  66. if (jumpOffset >= oldOffset) {
  67. // Allow only pointers to prior data. RFC 1035, section 4.1.4 states:
  68. // "[...] an entire domain name or a list of labels at the end of a domain name
  69. // is replaced with a pointer to a prior occurance (sic) of the same name."
  70. throw new Error('Cannot decode name (bad pointer)')
  71. }
  72. offset = jumpOffset
  73. oldOffset = jumpOffset
  74. consumedBytes += jumped ? 0 : 1
  75. jumped = true
  76. } else {
  77. throw new Error('Cannot decode name (bad label)')
  78. }
  79. }
  80. name.decode.bytes = consumedBytes
  81. return list.length === 0 ? '.' : list.join('.')
  82. }
  83. name.decode.bytes = 0
  84. name.encodingLength = function (n) {
  85. if (n === '.' || n === '..') return 1
  86. return Buffer.byteLength(n.replace(/^\.|\.$/gm, '')) + 2
  87. }
  88. const string = {}
  89. string.encode = function (s, buf, offset) {
  90. if (!buf) buf = Buffer.alloc(string.encodingLength(s))
  91. if (!offset) offset = 0
  92. const len = buf.write(s, offset + 1)
  93. buf[offset] = len
  94. string.encode.bytes = len + 1
  95. return buf
  96. }
  97. string.encode.bytes = 0
  98. string.decode = function (buf, offset) {
  99. if (!offset) offset = 0
  100. const len = buf[offset]
  101. const s = buf.toString('utf-8', offset + 1, offset + 1 + len)
  102. string.decode.bytes = len + 1
  103. return s
  104. }
  105. string.decode.bytes = 0
  106. string.encodingLength = function (s) {
  107. return Buffer.byteLength(s) + 1
  108. }
  109. const header = {}
  110. header.encode = function (h, buf, offset) {
  111. if (!buf) buf = header.encodingLength(h)
  112. if (!offset) offset = 0
  113. const flags = (h.flags || 0) & 32767
  114. const type = h.type === 'response' ? RESPONSE_FLAG : QUERY_FLAG
  115. buf.writeUInt16BE(h.id || 0, offset)
  116. buf.writeUInt16BE(flags | type, offset + 2)
  117. buf.writeUInt16BE(h.questions.length, offset + 4)
  118. buf.writeUInt16BE(h.answers.length, offset + 6)
  119. buf.writeUInt16BE(h.authorities.length, offset + 8)
  120. buf.writeUInt16BE(h.additionals.length, offset + 10)
  121. return buf
  122. }
  123. header.encode.bytes = 12
  124. header.decode = function (buf, offset) {
  125. if (!offset) offset = 0
  126. if (buf.length < 12) throw new Error('Header must be 12 bytes')
  127. const flags = buf.readUInt16BE(offset + 2)
  128. return {
  129. id: buf.readUInt16BE(offset),
  130. type: flags & RESPONSE_FLAG ? 'response' : 'query',
  131. flags: flags & 32767,
  132. flag_qr: ((flags >> 15) & 0x1) === 1,
  133. opcode: opcodes.toString((flags >> 11) & 0xf),
  134. flag_aa: ((flags >> 10) & 0x1) === 1,
  135. flag_tc: ((flags >> 9) & 0x1) === 1,
  136. flag_rd: ((flags >> 8) & 0x1) === 1,
  137. flag_ra: ((flags >> 7) & 0x1) === 1,
  138. flag_z: ((flags >> 6) & 0x1) === 1,
  139. flag_ad: ((flags >> 5) & 0x1) === 1,
  140. flag_cd: ((flags >> 4) & 0x1) === 1,
  141. rcode: rcodes.toString(flags & 0xf),
  142. questions: new Array(buf.readUInt16BE(offset + 4)),
  143. answers: new Array(buf.readUInt16BE(offset + 6)),
  144. authorities: new Array(buf.readUInt16BE(offset + 8)),
  145. additionals: new Array(buf.readUInt16BE(offset + 10))
  146. }
  147. }
  148. header.decode.bytes = 12
  149. header.encodingLength = function () {
  150. return 12
  151. }
  152. const runknown = exports.unknown = {}
  153. runknown.encode = function (data, buf, offset) {
  154. if (!buf) buf = Buffer.alloc(runknown.encodingLength(data))
  155. if (!offset) offset = 0
  156. buf.writeUInt16BE(data.length, offset)
  157. data.copy(buf, offset + 2)
  158. runknown.encode.bytes = data.length + 2
  159. return buf
  160. }
  161. runknown.encode.bytes = 0
  162. runknown.decode = function (buf, offset) {
  163. if (!offset) offset = 0
  164. const len = buf.readUInt16BE(offset)
  165. const data = buf.slice(offset + 2, offset + 2 + len)
  166. runknown.decode.bytes = len + 2
  167. return data
  168. }
  169. runknown.decode.bytes = 0
  170. runknown.encodingLength = function (data) {
  171. return data.length + 2
  172. }
  173. const rns = exports.ns = {}
  174. rns.encode = function (data, buf, offset) {
  175. if (!buf) buf = Buffer.alloc(rns.encodingLength(data))
  176. if (!offset) offset = 0
  177. name.encode(data, buf, offset + 2)
  178. buf.writeUInt16BE(name.encode.bytes, offset)
  179. rns.encode.bytes = name.encode.bytes + 2
  180. return buf
  181. }
  182. rns.encode.bytes = 0
  183. rns.decode = function (buf, offset) {
  184. if (!offset) offset = 0
  185. const len = buf.readUInt16BE(offset)
  186. const dd = name.decode(buf, offset + 2)
  187. rns.decode.bytes = len + 2
  188. return dd
  189. }
  190. rns.decode.bytes = 0
  191. rns.encodingLength = function (data) {
  192. return name.encodingLength(data) + 2
  193. }
  194. const rsoa = exports.soa = {}
  195. rsoa.encode = function (data, buf, offset) {
  196. if (!buf) buf = Buffer.alloc(rsoa.encodingLength(data))
  197. if (!offset) offset = 0
  198. const oldOffset = offset
  199. offset += 2
  200. name.encode(data.mname, buf, offset)
  201. offset += name.encode.bytes
  202. name.encode(data.rname, buf, offset)
  203. offset += name.encode.bytes
  204. buf.writeUInt32BE(data.serial || 0, offset)
  205. offset += 4
  206. buf.writeUInt32BE(data.refresh || 0, offset)
  207. offset += 4
  208. buf.writeUInt32BE(data.retry || 0, offset)
  209. offset += 4
  210. buf.writeUInt32BE(data.expire || 0, offset)
  211. offset += 4
  212. buf.writeUInt32BE(data.minimum || 0, offset)
  213. offset += 4
  214. buf.writeUInt16BE(offset - oldOffset - 2, oldOffset)
  215. rsoa.encode.bytes = offset - oldOffset
  216. return buf
  217. }
  218. rsoa.encode.bytes = 0
  219. rsoa.decode = function (buf, offset) {
  220. if (!offset) offset = 0
  221. const oldOffset = offset
  222. const data = {}
  223. offset += 2
  224. data.mname = name.decode(buf, offset)
  225. offset += name.decode.bytes
  226. data.rname = name.decode(buf, offset)
  227. offset += name.decode.bytes
  228. data.serial = buf.readUInt32BE(offset)
  229. offset += 4
  230. data.refresh = buf.readUInt32BE(offset)
  231. offset += 4
  232. data.retry = buf.readUInt32BE(offset)
  233. offset += 4
  234. data.expire = buf.readUInt32BE(offset)
  235. offset += 4
  236. data.minimum = buf.readUInt32BE(offset)
  237. offset += 4
  238. rsoa.decode.bytes = offset - oldOffset
  239. return data
  240. }
  241. rsoa.decode.bytes = 0
  242. rsoa.encodingLength = function (data) {
  243. return 22 + name.encodingLength(data.mname) + name.encodingLength(data.rname)
  244. }
  245. const rtxt = exports.txt = {}
  246. rtxt.encode = function (data, buf, offset) {
  247. if (!Array.isArray(data)) data = [data]
  248. for (let i = 0; i < data.length; i++) {
  249. if (typeof data[i] === 'string') {
  250. data[i] = Buffer.from(data[i])
  251. }
  252. if (!Buffer.isBuffer(data[i])) {
  253. throw new Error('Must be a Buffer')
  254. }
  255. }
  256. if (!buf) buf = Buffer.alloc(rtxt.encodingLength(data))
  257. if (!offset) offset = 0
  258. const oldOffset = offset
  259. offset += 2
  260. data.forEach(function (d) {
  261. buf[offset++] = d.length
  262. d.copy(buf, offset, 0, d.length)
  263. offset += d.length
  264. })
  265. buf.writeUInt16BE(offset - oldOffset - 2, oldOffset)
  266. rtxt.encode.bytes = offset - oldOffset
  267. return buf
  268. }
  269. rtxt.encode.bytes = 0
  270. rtxt.decode = function (buf, offset) {
  271. if (!offset) offset = 0
  272. const oldOffset = offset
  273. let remaining = buf.readUInt16BE(offset)
  274. offset += 2
  275. let data = []
  276. while (remaining > 0) {
  277. const len = buf[offset++]
  278. --remaining
  279. if (remaining < len) {
  280. throw new Error('Buffer overflow')
  281. }
  282. data.push(buf.slice(offset, offset + len))
  283. offset += len
  284. remaining -= len
  285. }
  286. rtxt.decode.bytes = offset - oldOffset
  287. return data
  288. }
  289. rtxt.decode.bytes = 0
  290. rtxt.encodingLength = function (data) {
  291. if (!Array.isArray(data)) data = [data]
  292. let length = 2
  293. data.forEach(function (buf) {
  294. if (typeof buf === 'string') {
  295. length += Buffer.byteLength(buf) + 1
  296. } else {
  297. length += buf.length + 1
  298. }
  299. })
  300. return length
  301. }
  302. const rnull = exports.null = {}
  303. rnull.encode = function (data, buf, offset) {
  304. if (!buf) buf = Buffer.alloc(rnull.encodingLength(data))
  305. if (!offset) offset = 0
  306. if (typeof data === 'string') data = Buffer.from(data)
  307. if (!data) data = Buffer.alloc(0)
  308. const oldOffset = offset
  309. offset += 2
  310. const len = data.length
  311. data.copy(buf, offset, 0, len)
  312. offset += len
  313. buf.writeUInt16BE(offset - oldOffset - 2, oldOffset)
  314. rnull.encode.bytes = offset - oldOffset
  315. return buf
  316. }
  317. rnull.encode.bytes = 0
  318. rnull.decode = function (buf, offset) {
  319. if (!offset) offset = 0
  320. const oldOffset = offset
  321. const len = buf.readUInt16BE(offset)
  322. offset += 2
  323. const data = buf.slice(offset, offset + len)
  324. offset += len
  325. rnull.decode.bytes = offset - oldOffset
  326. return data
  327. }
  328. rnull.decode.bytes = 0
  329. rnull.encodingLength = function (data) {
  330. if (!data) return 2
  331. return (Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data)) + 2
  332. }
  333. const rhinfo = exports.hinfo = {}
  334. rhinfo.encode = function (data, buf, offset) {
  335. if (!buf) buf = Buffer.alloc(rhinfo.encodingLength(data))
  336. if (!offset) offset = 0
  337. const oldOffset = offset
  338. offset += 2
  339. string.encode(data.cpu, buf, offset)
  340. offset += string.encode.bytes
  341. string.encode(data.os, buf, offset)
  342. offset += string.encode.bytes
  343. buf.writeUInt16BE(offset - oldOffset - 2, oldOffset)
  344. rhinfo.encode.bytes = offset - oldOffset
  345. return buf
  346. }
  347. rhinfo.encode.bytes = 0
  348. rhinfo.decode = function (buf, offset) {
  349. if (!offset) offset = 0
  350. const oldOffset = offset
  351. const data = {}
  352. offset += 2
  353. data.cpu = string.decode(buf, offset)
  354. offset += string.decode.bytes
  355. data.os = string.decode(buf, offset)
  356. offset += string.decode.bytes
  357. rhinfo.decode.bytes = offset - oldOffset
  358. return data
  359. }
  360. rhinfo.decode.bytes = 0
  361. rhinfo.encodingLength = function (data) {
  362. return string.encodingLength(data.cpu) + string.encodingLength(data.os) + 2
  363. }
  364. const rptr = exports.ptr = {}
  365. const rcname = exports.cname = rptr
  366. const rdname = exports.dname = rptr
  367. rptr.encode = function (data, buf, offset) {
  368. if (!buf) buf = Buffer.alloc(rptr.encodingLength(data))
  369. if (!offset) offset = 0
  370. name.encode(data, buf, offset + 2)
  371. buf.writeUInt16BE(name.encode.bytes, offset)
  372. rptr.encode.bytes = name.encode.bytes + 2
  373. return buf
  374. }
  375. rptr.encode.bytes = 0
  376. rptr.decode = function (buf, offset) {
  377. if (!offset) offset = 0
  378. const data = name.decode(buf, offset + 2)
  379. rptr.decode.bytes = name.decode.bytes + 2
  380. return data
  381. }
  382. rptr.decode.bytes = 0
  383. rptr.encodingLength = function (data) {
  384. return name.encodingLength(data) + 2
  385. }
  386. const rsrv = exports.srv = {}
  387. rsrv.encode = function (data, buf, offset) {
  388. if (!buf) buf = Buffer.alloc(rsrv.encodingLength(data))
  389. if (!offset) offset = 0
  390. buf.writeUInt16BE(data.priority || 0, offset + 2)
  391. buf.writeUInt16BE(data.weight || 0, offset + 4)
  392. buf.writeUInt16BE(data.port || 0, offset + 6)
  393. name.encode(data.target, buf, offset + 8)
  394. const len = name.encode.bytes + 6
  395. buf.writeUInt16BE(len, offset)
  396. rsrv.encode.bytes = len + 2
  397. return buf
  398. }
  399. rsrv.encode.bytes = 0
  400. rsrv.decode = function (buf, offset) {
  401. if (!offset) offset = 0
  402. const len = buf.readUInt16BE(offset)
  403. const data = {}
  404. data.priority = buf.readUInt16BE(offset + 2)
  405. data.weight = buf.readUInt16BE(offset + 4)
  406. data.port = buf.readUInt16BE(offset + 6)
  407. data.target = name.decode(buf, offset + 8)
  408. rsrv.decode.bytes = len + 2
  409. return data
  410. }
  411. rsrv.decode.bytes = 0
  412. rsrv.encodingLength = function (data) {
  413. return 8 + name.encodingLength(data.target)
  414. }
  415. const rcaa = exports.caa = {}
  416. rcaa.ISSUER_CRITICAL = 1 << 7
  417. rcaa.encode = function (data, buf, offset) {
  418. const len = rcaa.encodingLength(data)
  419. if (!buf) buf = Buffer.alloc(rcaa.encodingLength(data))
  420. if (!offset) offset = 0
  421. if (data.issuerCritical) {
  422. data.flags = rcaa.ISSUER_CRITICAL
  423. }
  424. buf.writeUInt16BE(len - 2, offset)
  425. offset += 2
  426. buf.writeUInt8(data.flags || 0, offset)
  427. offset += 1
  428. string.encode(data.tag, buf, offset)
  429. offset += string.encode.bytes
  430. buf.write(data.value, offset)
  431. offset += Buffer.byteLength(data.value)
  432. rcaa.encode.bytes = len
  433. return buf
  434. }
  435. rcaa.encode.bytes = 0
  436. rcaa.decode = function (buf, offset) {
  437. if (!offset) offset = 0
  438. const len = buf.readUInt16BE(offset)
  439. offset += 2
  440. const oldOffset = offset
  441. const data = {}
  442. data.flags = buf.readUInt8(offset)
  443. offset += 1
  444. data.tag = string.decode(buf, offset)
  445. offset += string.decode.bytes
  446. data.value = buf.toString('utf-8', offset, oldOffset + len)
  447. data.issuerCritical = !!(data.flags & rcaa.ISSUER_CRITICAL)
  448. rcaa.decode.bytes = len + 2
  449. return data
  450. }
  451. rcaa.decode.bytes = 0
  452. rcaa.encodingLength = function (data) {
  453. return string.encodingLength(data.tag) + string.encodingLength(data.value) + 2
  454. }
  455. const rmx = exports.mx = {}
  456. rmx.encode = function (data, buf, offset) {
  457. if (!buf) buf = Buffer.alloc(rmx.encodingLength(data))
  458. if (!offset) offset = 0
  459. const oldOffset = offset
  460. offset += 2
  461. buf.writeUInt16BE(data.preference || 0, offset)
  462. offset += 2
  463. name.encode(data.exchange, buf, offset)
  464. offset += name.encode.bytes
  465. buf.writeUInt16BE(offset - oldOffset - 2, oldOffset)
  466. rmx.encode.bytes = offset - oldOffset
  467. return buf
  468. }
  469. rmx.encode.bytes = 0
  470. rmx.decode = function (buf, offset) {
  471. if (!offset) offset = 0
  472. const oldOffset = offset
  473. const data = {}
  474. offset += 2
  475. data.preference = buf.readUInt16BE(offset)
  476. offset += 2
  477. data.exchange = name.decode(buf, offset)
  478. offset += name.decode.bytes
  479. rmx.decode.bytes = offset - oldOffset
  480. return data
  481. }
  482. rmx.encodingLength = function (data) {
  483. return 4 + name.encodingLength(data.exchange)
  484. }
  485. const ra = exports.a = {}
  486. ra.encode = function (host, buf, offset) {
  487. if (!buf) buf = Buffer.alloc(ra.encodingLength(host))
  488. if (!offset) offset = 0
  489. buf.writeUInt16BE(4, offset)
  490. offset += 2
  491. ip.v4.encode(host, buf, offset)
  492. ra.encode.bytes = 6
  493. return buf
  494. }
  495. ra.encode.bytes = 0
  496. ra.decode = function (buf, offset) {
  497. if (!offset) offset = 0
  498. offset += 2
  499. const host = ip.v4.decode(buf, offset)
  500. ra.decode.bytes = 6
  501. return host
  502. }
  503. ra.decode.bytes = 0
  504. ra.encodingLength = function () {
  505. return 6
  506. }
  507. const raaaa = exports.aaaa = {}
  508. raaaa.encode = function (host, buf, offset) {
  509. if (!buf) buf = Buffer.alloc(raaaa.encodingLength(host))
  510. if (!offset) offset = 0
  511. buf.writeUInt16BE(16, offset)
  512. offset += 2
  513. ip.v6.encode(host, buf, offset)
  514. raaaa.encode.bytes = 18
  515. return buf
  516. }
  517. raaaa.encode.bytes = 0
  518. raaaa.decode = function (buf, offset) {
  519. if (!offset) offset = 0
  520. offset += 2
  521. const host = ip.v6.decode(buf, offset)
  522. raaaa.decode.bytes = 18
  523. return host
  524. }
  525. raaaa.decode.bytes = 0
  526. raaaa.encodingLength = function () {
  527. return 18
  528. }
  529. const roption = exports.option = {}
  530. roption.encode = function (option, buf, offset) {
  531. if (!buf) buf = Buffer.alloc(roption.encodingLength(option))
  532. if (!offset) offset = 0
  533. const oldOffset = offset
  534. const code = optioncodes.toCode(option.code)
  535. buf.writeUInt16BE(code, offset)
  536. offset += 2
  537. if (option.data) {
  538. buf.writeUInt16BE(option.data.length, offset)
  539. offset += 2
  540. option.data.copy(buf, offset)
  541. offset += option.data.length
  542. } else {
  543. switch (code) {
  544. // case 3: NSID. No encode makes sense.
  545. // case 5,6,7: Not implementable
  546. case 8: // ECS
  547. // note: do IP math before calling
  548. const spl = option.sourcePrefixLength || 0
  549. const fam = option.family || ip.familyOf(option.ip)
  550. const ipBuf = ip.encode(option.ip, Buffer.alloc)
  551. const ipLen = Math.ceil(spl / 8)
  552. buf.writeUInt16BE(ipLen + 4, offset)
  553. offset += 2
  554. buf.writeUInt16BE(fam, offset)
  555. offset += 2
  556. buf.writeUInt8(spl, offset++)
  557. buf.writeUInt8(option.scopePrefixLength || 0, offset++)
  558. ipBuf.copy(buf, offset, 0, ipLen)
  559. offset += ipLen
  560. break
  561. // case 9: EXPIRE (experimental)
  562. // case 10: COOKIE. No encode makes sense.
  563. case 11: // KEEP-ALIVE
  564. if (option.timeout) {
  565. buf.writeUInt16BE(2, offset)
  566. offset += 2
  567. buf.writeUInt16BE(option.timeout, offset)
  568. offset += 2
  569. } else {
  570. buf.writeUInt16BE(0, offset)
  571. offset += 2
  572. }
  573. break
  574. case 12: // PADDING
  575. const len = option.length || 0
  576. buf.writeUInt16BE(len, offset)
  577. offset += 2
  578. buf.fill(0, offset, offset + len)
  579. offset += len
  580. break
  581. // case 13: CHAIN. Experimental.
  582. case 14: // KEY-TAG
  583. const tagsLen = option.tags.length * 2
  584. buf.writeUInt16BE(tagsLen, offset)
  585. offset += 2
  586. for (const tag of option.tags) {
  587. buf.writeUInt16BE(tag, offset)
  588. offset += 2
  589. }
  590. break
  591. default:
  592. throw new Error(`Unknown roption code: ${option.code}`)
  593. }
  594. }
  595. roption.encode.bytes = offset - oldOffset
  596. return buf
  597. }
  598. roption.encode.bytes = 0
  599. roption.decode = function (buf, offset) {
  600. if (!offset) offset = 0
  601. const option = {}
  602. option.code = buf.readUInt16BE(offset)
  603. option.type = optioncodes.toString(option.code)
  604. offset += 2
  605. const len = buf.readUInt16BE(offset)
  606. offset += 2
  607. option.data = buf.slice(offset, offset + len)
  608. switch (option.code) {
  609. // case 3: NSID. No decode makes sense.
  610. case 8: // ECS
  611. option.family = buf.readUInt16BE(offset)
  612. offset += 2
  613. option.sourcePrefixLength = buf.readUInt8(offset++)
  614. option.scopePrefixLength = buf.readUInt8(offset++)
  615. const padded = Buffer.alloc((option.family === 1) ? 4 : 16)
  616. buf.copy(padded, 0, offset, offset + len - 4)
  617. option.ip = ip.decode(padded)
  618. break
  619. // case 12: Padding. No decode makes sense.
  620. case 11: // KEEP-ALIVE
  621. if (len > 0) {
  622. option.timeout = buf.readUInt16BE(offset)
  623. offset += 2
  624. }
  625. break
  626. case 14:
  627. option.tags = []
  628. for (let i = 0; i < len; i += 2) {
  629. option.tags.push(buf.readUInt16BE(offset))
  630. offset += 2
  631. }
  632. // don't worry about default. caller will use data if desired
  633. }
  634. roption.decode.bytes = len + 4
  635. return option
  636. }
  637. roption.decode.bytes = 0
  638. roption.encodingLength = function (option) {
  639. if (option.data) {
  640. return option.data.length + 4
  641. }
  642. const code = optioncodes.toCode(option.code)
  643. switch (code) {
  644. case 8: // ECS
  645. const spl = option.sourcePrefixLength || 0
  646. return Math.ceil(spl / 8) + 8
  647. case 11: // KEEP-ALIVE
  648. return (typeof option.timeout === 'number') ? 6 : 4
  649. case 12: // PADDING
  650. return option.length + 4
  651. case 14: // KEY-TAG
  652. return 4 + (option.tags.length * 2)
  653. }
  654. throw new Error(`Unknown roption code: ${option.code}`)
  655. }
  656. const ropt = exports.opt = {}
  657. ropt.encode = function (options, buf, offset) {
  658. if (!buf) buf = Buffer.alloc(ropt.encodingLength(options))
  659. if (!offset) offset = 0
  660. const oldOffset = offset
  661. const rdlen = encodingLengthList(options, roption)
  662. buf.writeUInt16BE(rdlen, offset)
  663. offset = encodeList(options, roption, buf, offset + 2)
  664. ropt.encode.bytes = offset - oldOffset
  665. return buf
  666. }
  667. ropt.encode.bytes = 0
  668. ropt.decode = function (buf, offset) {
  669. if (!offset) offset = 0
  670. const oldOffset = offset
  671. const options = []
  672. let rdlen = buf.readUInt16BE(offset)
  673. offset += 2
  674. let o = 0
  675. while (rdlen > 0) {
  676. options[o++] = roption.decode(buf, offset)
  677. offset += roption.decode.bytes
  678. rdlen -= roption.decode.bytes
  679. }
  680. ropt.decode.bytes = offset - oldOffset
  681. return options
  682. }
  683. ropt.decode.bytes = 0
  684. ropt.encodingLength = function (options) {
  685. return 2 + encodingLengthList(options || [], roption)
  686. }
  687. const rdnskey = exports.dnskey = {}
  688. rdnskey.PROTOCOL_DNSSEC = 3
  689. rdnskey.ZONE_KEY = 0x80
  690. rdnskey.SECURE_ENTRYPOINT = 0x8000
  691. rdnskey.encode = function (key, buf, offset) {
  692. if (!buf) buf = Buffer.alloc(rdnskey.encodingLength(key))
  693. if (!offset) offset = 0
  694. const oldOffset = offset
  695. const keydata = key.key
  696. if (!Buffer.isBuffer(keydata)) {
  697. throw new Error('Key must be a Buffer')
  698. }
  699. offset += 2 // Leave space for length
  700. buf.writeUInt16BE(key.flags, offset)
  701. offset += 2
  702. buf.writeUInt8(rdnskey.PROTOCOL_DNSSEC, offset)
  703. offset += 1
  704. buf.writeUInt8(key.algorithm, offset)
  705. offset += 1
  706. keydata.copy(buf, offset, 0, keydata.length)
  707. offset += keydata.length
  708. rdnskey.encode.bytes = offset - oldOffset
  709. buf.writeUInt16BE(rdnskey.encode.bytes - 2, oldOffset)
  710. return buf
  711. }
  712. rdnskey.encode.bytes = 0
  713. rdnskey.decode = function (buf, offset) {
  714. if (!offset) offset = 0
  715. const oldOffset = offset
  716. var key = {}
  717. var length = buf.readUInt16BE(offset)
  718. offset += 2
  719. key.flags = buf.readUInt16BE(offset)
  720. offset += 2
  721. if (buf.readUInt8(offset) !== rdnskey.PROTOCOL_DNSSEC) {
  722. throw new Error('Protocol must be 3')
  723. }
  724. offset += 1
  725. key.algorithm = buf.readUInt8(offset)
  726. offset += 1
  727. key.key = buf.slice(offset, oldOffset + length + 2)
  728. offset += key.key.length
  729. rdnskey.decode.bytes = offset - oldOffset
  730. return key
  731. }
  732. rdnskey.decode.bytes = 0
  733. rdnskey.encodingLength = function (key) {
  734. return 6 + Buffer.byteLength(key.key)
  735. }
  736. const rrrsig = exports.rrsig = {}
  737. rrrsig.encode = function (sig, buf, offset) {
  738. if (!buf) buf = Buffer.alloc(rrrsig.encodingLength(sig))
  739. if (!offset) offset = 0
  740. const oldOffset = offset
  741. const signature = sig.signature
  742. if (!Buffer.isBuffer(signature)) {
  743. throw new Error('Signature must be a Buffer')
  744. }
  745. offset += 2 // Leave space for length
  746. buf.writeUInt16BE(types.toType(sig.typeCovered), offset)
  747. offset += 2
  748. buf.writeUInt8(sig.algorithm, offset)
  749. offset += 1
  750. buf.writeUInt8(sig.labels, offset)
  751. offset += 1
  752. buf.writeUInt32BE(sig.originalTTL, offset)
  753. offset += 4
  754. buf.writeUInt32BE(sig.expiration, offset)
  755. offset += 4
  756. buf.writeUInt32BE(sig.inception, offset)
  757. offset += 4
  758. buf.writeUInt16BE(sig.keyTag, offset)
  759. offset += 2
  760. name.encode(sig.signersName, buf, offset)
  761. offset += name.encode.bytes
  762. signature.copy(buf, offset, 0, signature.length)
  763. offset += signature.length
  764. rrrsig.encode.bytes = offset - oldOffset
  765. buf.writeUInt16BE(rrrsig.encode.bytes - 2, oldOffset)
  766. return buf
  767. }
  768. rrrsig.encode.bytes = 0
  769. rrrsig.decode = function (buf, offset) {
  770. if (!offset) offset = 0
  771. const oldOffset = offset
  772. var sig = {}
  773. var length = buf.readUInt16BE(offset)
  774. offset += 2
  775. sig.typeCovered = types.toString(buf.readUInt16BE(offset))
  776. offset += 2
  777. sig.algorithm = buf.readUInt8(offset)
  778. offset += 1
  779. sig.labels = buf.readUInt8(offset)
  780. offset += 1
  781. sig.originalTTL = buf.readUInt32BE(offset)
  782. offset += 4
  783. sig.expiration = buf.readUInt32BE(offset)
  784. offset += 4
  785. sig.inception = buf.readUInt32BE(offset)
  786. offset += 4
  787. sig.keyTag = buf.readUInt16BE(offset)
  788. offset += 2
  789. sig.signersName = name.decode(buf, offset)
  790. offset += name.decode.bytes
  791. sig.signature = buf.slice(offset, oldOffset + length + 2)
  792. offset += sig.signature.length
  793. rrrsig.decode.bytes = offset - oldOffset
  794. return sig
  795. }
  796. rrrsig.decode.bytes = 0
  797. rrrsig.encodingLength = function (sig) {
  798. return 20 +
  799. name.encodingLength(sig.signersName) +
  800. Buffer.byteLength(sig.signature)
  801. }
  802. const rrp = exports.rp = {}
  803. rrp.encode = function (data, buf, offset) {
  804. if (!buf) buf = Buffer.alloc(rrp.encodingLength(data))
  805. if (!offset) offset = 0
  806. const oldOffset = offset
  807. offset += 2 // Leave space for length
  808. name.encode(data.mbox || '.', buf, offset)
  809. offset += name.encode.bytes
  810. name.encode(data.txt || '.', buf, offset)
  811. offset += name.encode.bytes
  812. rrp.encode.bytes = offset - oldOffset
  813. buf.writeUInt16BE(rrp.encode.bytes - 2, oldOffset)
  814. return buf
  815. }
  816. rrp.encode.bytes = 0
  817. rrp.decode = function (buf, offset) {
  818. if (!offset) offset = 0
  819. const oldOffset = offset
  820. const data = {}
  821. offset += 2
  822. data.mbox = name.decode(buf, offset) || '.'
  823. offset += name.decode.bytes
  824. data.txt = name.decode(buf, offset) || '.'
  825. offset += name.decode.bytes
  826. rrp.decode.bytes = offset - oldOffset
  827. return data
  828. }
  829. rrp.decode.bytes = 0
  830. rrp.encodingLength = function (data) {
  831. return 2 + name.encodingLength(data.mbox || '.') + name.encodingLength(data.txt || '.')
  832. }
  833. const typebitmap = {}
  834. typebitmap.encode = function (typelist, buf, offset) {
  835. if (!buf) buf = Buffer.alloc(typebitmap.encodingLength(typelist))
  836. if (!offset) offset = 0
  837. const oldOffset = offset
  838. var typesByWindow = []
  839. for (var i = 0; i < typelist.length; i++) {
  840. var typeid = types.toType(typelist[i])
  841. if (typesByWindow[typeid >> 8] === undefined) {
  842. typesByWindow[typeid >> 8] = []
  843. }
  844. typesByWindow[typeid >> 8][(typeid >> 3) & 0x1F] |= 1 << (7 - (typeid & 0x7))
  845. }
  846. for (i = 0; i < typesByWindow.length; i++) {
  847. if (typesByWindow[i] !== undefined) {
  848. var windowBuf = Buffer.from(typesByWindow[i])
  849. buf.writeUInt8(i, offset)
  850. offset += 1
  851. buf.writeUInt8(windowBuf.length, offset)
  852. offset += 1
  853. windowBuf.copy(buf, offset)
  854. offset += windowBuf.length
  855. }
  856. }
  857. typebitmap.encode.bytes = offset - oldOffset
  858. return buf
  859. }
  860. typebitmap.encode.bytes = 0
  861. typebitmap.decode = function (buf, offset, length) {
  862. if (!offset) offset = 0
  863. const oldOffset = offset
  864. var typelist = []
  865. while (offset - oldOffset < length) {
  866. var window = buf.readUInt8(offset)
  867. offset += 1
  868. var windowLength = buf.readUInt8(offset)
  869. offset += 1
  870. for (var i = 0; i < windowLength; i++) {
  871. var b = buf.readUInt8(offset + i)
  872. for (var j = 0; j < 8; j++) {
  873. if (b & (1 << (7 - j))) {
  874. var typeid = types.toString((window << 8) | (i << 3) | j)
  875. typelist.push(typeid)
  876. }
  877. }
  878. }
  879. offset += windowLength
  880. }
  881. typebitmap.decode.bytes = offset - oldOffset
  882. return typelist
  883. }
  884. typebitmap.decode.bytes = 0
  885. typebitmap.encodingLength = function (typelist) {
  886. var extents = []
  887. for (var i = 0; i < typelist.length; i++) {
  888. var typeid = types.toType(typelist[i])
  889. extents[typeid >> 8] = Math.max(extents[typeid >> 8] || 0, typeid & 0xFF)
  890. }
  891. var len = 0
  892. for (i = 0; i < extents.length; i++) {
  893. if (extents[i] !== undefined) {
  894. len += 2 + Math.ceil((extents[i] + 1) / 8)
  895. }
  896. }
  897. return len
  898. }
  899. const rnsec = exports.nsec = {}
  900. rnsec.encode = function (record, buf, offset) {
  901. if (!buf) buf = Buffer.alloc(rnsec.encodingLength(record))
  902. if (!offset) offset = 0
  903. const oldOffset = offset
  904. offset += 2 // Leave space for length
  905. name.encode(record.nextDomain, buf, offset)
  906. offset += name.encode.bytes
  907. typebitmap.encode(record.rrtypes, buf, offset)
  908. offset += typebitmap.encode.bytes
  909. rnsec.encode.bytes = offset - oldOffset
  910. buf.writeUInt16BE(rnsec.encode.bytes - 2, oldOffset)
  911. return buf
  912. }
  913. rnsec.encode.bytes = 0
  914. rnsec.decode = function (buf, offset) {
  915. if (!offset) offset = 0
  916. const oldOffset = offset
  917. var record = {}
  918. var length = buf.readUInt16BE(offset)
  919. offset += 2
  920. record.nextDomain = name.decode(buf, offset)
  921. offset += name.decode.bytes
  922. record.rrtypes = typebitmap.decode(buf, offset, length - (offset - oldOffset))
  923. offset += typebitmap.decode.bytes
  924. rnsec.decode.bytes = offset - oldOffset
  925. return record
  926. }
  927. rnsec.decode.bytes = 0
  928. rnsec.encodingLength = function (record) {
  929. return 2 +
  930. name.encodingLength(record.nextDomain) +
  931. typebitmap.encodingLength(record.rrtypes)
  932. }
  933. const rnsec3 = exports.nsec3 = {}
  934. rnsec3.encode = function (record, buf, offset) {
  935. if (!buf) buf = Buffer.alloc(rnsec3.encodingLength(record))
  936. if (!offset) offset = 0
  937. const oldOffset = offset
  938. const salt = record.salt
  939. if (!Buffer.isBuffer(salt)) {
  940. throw new Error('salt must be a Buffer')
  941. }
  942. const nextDomain = record.nextDomain
  943. if (!Buffer.isBuffer(nextDomain)) {
  944. throw new Error('nextDomain must be a Buffer')
  945. }
  946. offset += 2 // Leave space for length
  947. buf.writeUInt8(record.algorithm, offset)
  948. offset += 1
  949. buf.writeUInt8(record.flags, offset)
  950. offset += 1
  951. buf.writeUInt16BE(record.iterations, offset)
  952. offset += 2
  953. buf.writeUInt8(salt.length, offset)
  954. offset += 1
  955. salt.copy(buf, offset, 0, salt.length)
  956. offset += salt.length
  957. buf.writeUInt8(nextDomain.length, offset)
  958. offset += 1
  959. nextDomain.copy(buf, offset, 0, nextDomain.length)
  960. offset += nextDomain.length
  961. typebitmap.encode(record.rrtypes, buf, offset)
  962. offset += typebitmap.encode.bytes
  963. rnsec3.encode.bytes = offset - oldOffset
  964. buf.writeUInt16BE(rnsec3.encode.bytes - 2, oldOffset)
  965. return buf
  966. }
  967. rnsec3.encode.bytes = 0
  968. rnsec3.decode = function (buf, offset) {
  969. if (!offset) offset = 0
  970. const oldOffset = offset
  971. var record = {}
  972. var length = buf.readUInt16BE(offset)
  973. offset += 2
  974. record.algorithm = buf.readUInt8(offset)
  975. offset += 1
  976. record.flags = buf.readUInt8(offset)
  977. offset += 1
  978. record.iterations = buf.readUInt16BE(offset)
  979. offset += 2
  980. const saltLength = buf.readUInt8(offset)
  981. offset += 1
  982. record.salt = buf.slice(offset, offset + saltLength)
  983. offset += saltLength
  984. const hashLength = buf.readUInt8(offset)
  985. offset += 1
  986. record.nextDomain = buf.slice(offset, offset + hashLength)
  987. offset += hashLength
  988. record.rrtypes = typebitmap.decode(buf, offset, length - (offset - oldOffset))
  989. offset += typebitmap.decode.bytes
  990. rnsec3.decode.bytes = offset - oldOffset
  991. return record
  992. }
  993. rnsec3.decode.bytes = 0
  994. rnsec3.encodingLength = function (record) {
  995. return 8 +
  996. record.salt.length +
  997. record.nextDomain.length +
  998. typebitmap.encodingLength(record.rrtypes)
  999. }
  1000. const rds = exports.ds = {}
  1001. rds.encode = function (digest, buf, offset) {
  1002. if (!buf) buf = Buffer.alloc(rds.encodingLength(digest))
  1003. if (!offset) offset = 0
  1004. const oldOffset = offset
  1005. const digestdata = digest.digest
  1006. if (!Buffer.isBuffer(digestdata)) {
  1007. throw new Error('Digest must be a Buffer')
  1008. }
  1009. offset += 2 // Leave space for length
  1010. buf.writeUInt16BE(digest.keyTag, offset)
  1011. offset += 2
  1012. buf.writeUInt8(digest.algorithm, offset)
  1013. offset += 1
  1014. buf.writeUInt8(digest.digestType, offset)
  1015. offset += 1
  1016. digestdata.copy(buf, offset, 0, digestdata.length)
  1017. offset += digestdata.length
  1018. rds.encode.bytes = offset - oldOffset
  1019. buf.writeUInt16BE(rds.encode.bytes - 2, oldOffset)
  1020. return buf
  1021. }
  1022. rds.encode.bytes = 0
  1023. rds.decode = function (buf, offset) {
  1024. if (!offset) offset = 0
  1025. const oldOffset = offset
  1026. var digest = {}
  1027. var length = buf.readUInt16BE(offset)
  1028. offset += 2
  1029. digest.keyTag = buf.readUInt16BE(offset)
  1030. offset += 2
  1031. digest.algorithm = buf.readUInt8(offset)
  1032. offset += 1
  1033. digest.digestType = buf.readUInt8(offset)
  1034. offset += 1
  1035. digest.digest = buf.slice(offset, oldOffset + length + 2)
  1036. offset += digest.digest.length
  1037. rds.decode.bytes = offset - oldOffset
  1038. return digest
  1039. }
  1040. rds.decode.bytes = 0
  1041. rds.encodingLength = function (digest) {
  1042. return 6 + Buffer.byteLength(digest.digest)
  1043. }
  1044. const rsshfp = exports.sshfp = {}
  1045. rsshfp.getFingerprintLengthForHashType = function getFingerprintLengthForHashType (hashType) {
  1046. switch (hashType) {
  1047. case 1: return 20
  1048. case 2: return 32
  1049. }
  1050. }
  1051. rsshfp.encode = function encode (record, buf, offset) {
  1052. if (!buf) buf = Buffer.alloc(rsshfp.encodingLength(record))
  1053. if (!offset) offset = 0
  1054. const oldOffset = offset
  1055. offset += 2 // The function call starts with the offset pointer at the RDLENGTH field, not the RDATA one
  1056. buf[offset] = record.algorithm
  1057. offset += 1
  1058. buf[offset] = record.hash
  1059. offset += 1
  1060. const fingerprintBuf = Buffer.from(record.fingerprint.toUpperCase(), 'hex')
  1061. if (fingerprintBuf.length !== rsshfp.getFingerprintLengthForHashType(record.hash)) {
  1062. throw new Error('Invalid fingerprint length')
  1063. }
  1064. fingerprintBuf.copy(buf, offset)
  1065. offset += fingerprintBuf.byteLength
  1066. rsshfp.encode.bytes = offset - oldOffset
  1067. buf.writeUInt16BE(rsshfp.encode.bytes - 2, oldOffset)
  1068. return buf
  1069. }
  1070. rsshfp.encode.bytes = 0
  1071. rsshfp.decode = function decode (buf, offset) {
  1072. if (!offset) offset = 0
  1073. const oldOffset = offset
  1074. const record = {}
  1075. offset += 2 // Account for the RDLENGTH field
  1076. record.algorithm = buf[offset]
  1077. offset += 1
  1078. record.hash = buf[offset]
  1079. offset += 1
  1080. const fingerprintLength = rsshfp.getFingerprintLengthForHashType(record.hash)
  1081. record.fingerprint = buf.slice(offset, offset + fingerprintLength).toString('hex').toUpperCase()
  1082. offset += fingerprintLength
  1083. rsshfp.decode.bytes = offset - oldOffset
  1084. return record
  1085. }
  1086. rsshfp.decode.bytes = 0
  1087. rsshfp.encodingLength = function (record) {
  1088. return 4 + Buffer.from(record.fingerprint, 'hex').byteLength
  1089. }
  1090. const renc = exports.record = function (type) {
  1091. switch (type.toUpperCase()) {
  1092. case 'A': return ra
  1093. case 'PTR': return rptr
  1094. case 'CNAME': return rcname
  1095. case 'DNAME': return rdname
  1096. case 'TXT': return rtxt
  1097. case 'NULL': return rnull
  1098. case 'AAAA': return raaaa
  1099. case 'SRV': return rsrv
  1100. case 'HINFO': return rhinfo
  1101. case 'CAA': return rcaa
  1102. case 'NS': return rns
  1103. case 'SOA': return rsoa
  1104. case 'MX': return rmx
  1105. case 'OPT': return ropt
  1106. case 'DNSKEY': return rdnskey
  1107. case 'RRSIG': return rrrsig
  1108. case 'RP': return rrp
  1109. case 'NSEC': return rnsec
  1110. case 'NSEC3': return rnsec3
  1111. case 'SSHFP': return rsshfp
  1112. case 'DS': return rds
  1113. }
  1114. return runknown
  1115. }
  1116. const answer = exports.answer = {}
  1117. answer.encode = function (a, buf, offset) {
  1118. if (!buf) buf = Buffer.alloc(answer.encodingLength(a))
  1119. if (!offset) offset = 0
  1120. const oldOffset = offset
  1121. name.encode(a.name, buf, offset)
  1122. offset += name.encode.bytes
  1123. buf.writeUInt16BE(types.toType(a.type), offset)
  1124. if (a.type.toUpperCase() === 'OPT') {
  1125. if (a.name !== '.') {
  1126. throw new Error('OPT name must be root.')
  1127. }
  1128. buf.writeUInt16BE(a.udpPayloadSize || 4096, offset + 2)
  1129. buf.writeUInt8(a.extendedRcode || 0, offset + 4)
  1130. buf.writeUInt8(a.ednsVersion || 0, offset + 5)
  1131. buf.writeUInt16BE(a.flags || 0, offset + 6)
  1132. offset += 8
  1133. ropt.encode(a.options || [], buf, offset)
  1134. offset += ropt.encode.bytes
  1135. } else {
  1136. let klass = classes.toClass(a.class === undefined ? 'IN' : a.class)
  1137. if (a.flush) klass |= FLUSH_MASK // the 1st bit of the class is the flush bit
  1138. buf.writeUInt16BE(klass, offset + 2)
  1139. buf.writeUInt32BE(a.ttl || 0, offset + 4)
  1140. offset += 8
  1141. const enc = renc(a.type)
  1142. enc.encode(a.data, buf, offset)
  1143. offset += enc.encode.bytes
  1144. }
  1145. answer.encode.bytes = offset - oldOffset
  1146. return buf
  1147. }
  1148. answer.encode.bytes = 0
  1149. answer.decode = function (buf, offset) {
  1150. if (!offset) offset = 0
  1151. const a = {}
  1152. const oldOffset = offset
  1153. a.name = name.decode(buf, offset)
  1154. offset += name.decode.bytes
  1155. a.type = types.toString(buf.readUInt16BE(offset))
  1156. if (a.type === 'OPT') {
  1157. a.udpPayloadSize = buf.readUInt16BE(offset + 2)
  1158. a.extendedRcode = buf.readUInt8(offset + 4)
  1159. a.ednsVersion = buf.readUInt8(offset + 5)
  1160. a.flags = buf.readUInt16BE(offset + 6)
  1161. a.flag_do = ((a.flags >> 15) & 0x1) === 1
  1162. a.options = ropt.decode(buf, offset + 8)
  1163. offset += 8 + ropt.decode.bytes
  1164. } else {
  1165. const klass = buf.readUInt16BE(offset + 2)
  1166. a.ttl = buf.readUInt32BE(offset + 4)
  1167. a.class = classes.toString(klass & NOT_FLUSH_MASK)
  1168. a.flush = !!(klass & FLUSH_MASK)
  1169. const enc = renc(a.type)
  1170. a.data = enc.decode(buf, offset + 8)
  1171. offset += 8 + enc.decode.bytes
  1172. }
  1173. answer.decode.bytes = offset - oldOffset
  1174. return a
  1175. }
  1176. answer.decode.bytes = 0
  1177. answer.encodingLength = function (a) {
  1178. const data = (a.data !== null && a.data !== undefined) ? a.data : a.options
  1179. return name.encodingLength(a.name) + 8 + renc(a.type).encodingLength(data)
  1180. }
  1181. const question = exports.question = {}
  1182. question.encode = function (q, buf, offset) {
  1183. if (!buf) buf = Buffer.alloc(question.encodingLength(q))
  1184. if (!offset) offset = 0
  1185. const oldOffset = offset
  1186. name.encode(q.name, buf, offset)
  1187. offset += name.encode.bytes
  1188. buf.writeUInt16BE(types.toType(q.type), offset)
  1189. offset += 2
  1190. buf.writeUInt16BE(classes.toClass(q.class === undefined ? 'IN' : q.class), offset)
  1191. offset += 2
  1192. question.encode.bytes = offset - oldOffset
  1193. return q
  1194. }
  1195. question.encode.bytes = 0
  1196. question.decode = function (buf, offset) {
  1197. if (!offset) offset = 0
  1198. const oldOffset = offset
  1199. const q = {}
  1200. q.name = name.decode(buf, offset)
  1201. offset += name.decode.bytes
  1202. q.type = types.toString(buf.readUInt16BE(offset))
  1203. offset += 2
  1204. q.class = classes.toString(buf.readUInt16BE(offset))
  1205. offset += 2
  1206. const qu = !!(q.class & QU_MASK)
  1207. if (qu) q.class &= NOT_QU_MASK
  1208. question.decode.bytes = offset - oldOffset
  1209. return q
  1210. }
  1211. question.decode.bytes = 0
  1212. question.encodingLength = function (q) {
  1213. return name.encodingLength(q.name) + 4
  1214. }
  1215. exports.AUTHORITATIVE_ANSWER = 1 << 10
  1216. exports.TRUNCATED_RESPONSE = 1 << 9
  1217. exports.RECURSION_DESIRED = 1 << 8
  1218. exports.RECURSION_AVAILABLE = 1 << 7
  1219. exports.AUTHENTIC_DATA = 1 << 5
  1220. exports.CHECKING_DISABLED = 1 << 4
  1221. exports.DNSSEC_OK = 1 << 15
  1222. exports.encode = function (result, buf, offset) {
  1223. const allocing = !buf
  1224. if (allocing) buf = Buffer.alloc(exports.encodingLength(result))
  1225. if (!offset) offset = 0
  1226. const oldOffset = offset
  1227. if (!result.questions) result.questions = []
  1228. if (!result.answers) result.answers = []
  1229. if (!result.authorities) result.authorities = []
  1230. if (!result.additionals) result.additionals = []
  1231. header.encode(result, buf, offset)
  1232. offset += header.encode.bytes
  1233. offset = encodeList(result.questions, question, buf, offset)
  1234. offset = encodeList(result.answers, answer, buf, offset)
  1235. offset = encodeList(result.authorities, answer, buf, offset)
  1236. offset = encodeList(result.additionals, answer, buf, offset)
  1237. exports.encode.bytes = offset - oldOffset
  1238. // just a quick sanity check
  1239. if (allocing && exports.encode.bytes !== buf.length) {
  1240. return buf.slice(0, exports.encode.bytes)
  1241. }
  1242. return buf
  1243. }
  1244. exports.encode.bytes = 0
  1245. exports.decode = function (buf, offset) {
  1246. if (!offset) offset = 0
  1247. const oldOffset = offset
  1248. const result = header.decode(buf, offset)
  1249. offset += header.decode.bytes
  1250. offset = decodeList(result.questions, question, buf, offset)
  1251. offset = decodeList(result.answers, answer, buf, offset)
  1252. offset = decodeList(result.authorities, answer, buf, offset)
  1253. offset = decodeList(result.additionals, answer, buf, offset)
  1254. exports.decode.bytes = offset - oldOffset
  1255. return result
  1256. }
  1257. exports.decode.bytes = 0
  1258. exports.encodingLength = function (result) {
  1259. return header.encodingLength(result) +
  1260. encodingLengthList(result.questions || [], question) +
  1261. encodingLengthList(result.answers || [], answer) +
  1262. encodingLengthList(result.authorities || [], answer) +
  1263. encodingLengthList(result.additionals || [], answer)
  1264. }
  1265. exports.streamEncode = function (result) {
  1266. const buf = exports.encode(result)
  1267. const sbuf = Buffer.alloc(2)
  1268. sbuf.writeUInt16BE(buf.byteLength)
  1269. const combine = Buffer.concat([sbuf, buf])
  1270. exports.streamEncode.bytes = combine.byteLength
  1271. return combine
  1272. }
  1273. exports.streamEncode.bytes = 0
  1274. exports.streamDecode = function (sbuf) {
  1275. const len = sbuf.readUInt16BE(0)
  1276. if (sbuf.byteLength < len + 2) {
  1277. // not enough data
  1278. return null
  1279. }
  1280. const result = exports.decode(sbuf.slice(2))
  1281. exports.streamDecode.bytes = exports.decode.bytes
  1282. return result
  1283. }
  1284. exports.streamDecode.bytes = 0
  1285. function encodingLengthList (list, enc) {
  1286. let len = 0
  1287. for (let i = 0; i < list.length; i++) len += enc.encodingLength(list[i])
  1288. return len
  1289. }
  1290. function encodeList (list, enc, buf, offset) {
  1291. for (let i = 0; i < list.length; i++) {
  1292. enc.encode(list[i], buf, offset)
  1293. offset += enc.encode.bytes
  1294. }
  1295. return offset
  1296. }
  1297. function decodeList (list, enc, buf, offset) {
  1298. for (let i = 0; i < list.length; i++) {
  1299. list[i] = enc.decode(buf, offset)
  1300. offset += enc.decode.bytes
  1301. }
  1302. return offset
  1303. }