npm.io
0.1.8 • Published 6 months ago

extra-dns

Licence
MIT
Version
0.1.8
Deps
6
Size
118 kB
Vulns
0
Weekly
0

extra-dns

Install

npm install --save extra-dns
# or
yarn add extra-dns

Usage

import { DNSServer, DNSClient } from 'extra-dns'

const stopDNSForwarder = await startDNSForwarder({
  local: { host: '127.0.0.1', port: 53 }
, remote: { host: '8.8.8.8', port: 53 }
})

async function startDNSForwarder({ local, remote }: {
  local: { host: string; port: number }
  remote: { host: string; port: number }
}): Promise<() => Promise<void>> {
  const server = new DNSServer(local.host, local.port)
  const client = new DNSClient(remote.host, remote.port)

  server.on('query', async (query, respond) => {
    await respond(await client.resolve(query))
  })

  return await server.listen()
}

API

interface IPacket {
  header: IHeader
  questions: IQuestion[]
  answers: IResourceRecord[]
  authorityRecords: IResourceRecord[]
  additionalRecords: IResourceRecord[]
}

interface IHeader {
  ID: number
  flags: IFlags
}

interface IQuestion {
  QNAME: string
  QTYPE: number
  QCLASS: number
}

interface IResourceRecord<Type extends TYPE = number> {
  NAME: string
  TYPE: number
  CLASS: number
  TTL: number
  RDATA: ArrayBufferLike

  /**
   * `rdata` has higher priority than `RDATA`
   */
  rdata?:
  | A_RDATA
  | AAAA_RDATA
  | CNAME_RDATA
  | MX_RDATA
  | NS_RDATA
  | PTR_RDATA
  | SOA_RDATA
  | AFSDB_RDATA
  | NAPTR_RDATA
  | SRV_RDATA
  | null
}

interface IFlags {
  QR: QR
  OPCODE: number
  AA: number
  TC: number
  RD: number
  RA: number
  Z: number
  RCODE: number
}

enum QR { /*...*/ }
enum CLASS { /*...*/ }
enum TYPE { /*...*/ }
enum OPCODE { /* ... */ }
enum RCODE { /* ... */ }
DNSServer
import { Emitter } from '@blackglory/structures'

class DNSServer extends Emitter<{
  query: [
    query: IPacket
  , respond: (response: IPacket) => Promise<void>
  ]
}> {
  constructor(host: string, port: number, socket?: dgram.Socket)

  listen(): Promise<() => Promise<void>>
}
DNSClient
class DNSClient {
  constructor(host: string, port: number, socket?: dgram.Socket)

  close(): Promise<void>

  resolve(query: Packet, signal?: AbortSignal): Promise<Packet>
}
RDATA
A_RDATA
class A_RDATA {
  constructor(
    public ADDRESS: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): A_RDATA
}
AAAA_RDATA
class AAAA_RDATA {
  constructor(
    public ADDRESS: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): AAAA_RDATA
}
CNAME_RDATA
class CNAME_RDATA {
  constructor(
    public CNAME: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): CNAME_RDATA
}
MX_RDATA
class MX_RDATA {
  constructor(
    public PREFERENCE: number
  , public EXCHANGE: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): MX_RDATA
}
NS_RDATA
class NS_RDATA {
  constructor(
    public NSDNAME: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): NS_RDATA
}
PTR_RDATA
class PTR_RDATA {
  constructor(
    public PTRDNAME: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): PTR_RDATA
}
SOA_RDATA
class SOA_RDATA {
  constructor(
    public MNAME: string
  , public RNAME: string
  , public SERIAL: number
  , public REFRESH: number
  , public RETRY: number
  , public EXPIRE: number
  , public MINIMUM: number
  ) {}

  static decode(buffer: ArrayBufferLike, byteOffset: number): SOA_RDATA
}
AFSDB_RDATA
class AFSDB_RDATA {
  constructor(
    public SUBTYPE: number
  , public HOSTNAME: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): AFSDB_RDATA
}
NAPTR_RDATA
class NAPTR_RDATA {
  constructor(
    public ORDER: number
  , public PREFERENCE: number
  , public FLAGS: string
  , public SERVICES: string
  , public REGEXP: string
  , public REPLACEMENT: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): NAPTR_RDATA
}
SRV_RDATA
class SRV_RDATA {
  constructor(
    public PRIORITY: number
  , public WEIGHT: number
  , public PORT: number
  , public TARGET: string
  ) {}

  static decode(buffer: ArrayBufferLike, byteOffset: number): SRV_RDATA
}

Keywords