index.js 44 KB

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