# extra-dns

> ```sh npm install --save extra-dns # or yarn add extra-dns ```

Latest version **0.1.8** (published 2026-02-28) · MIT license · 0 weekly downloads

## Install

```sh
npm install extra-dns
pnpm add extra-dns
yarn add extra-dns
bun add extra-dns
```

## Health

**Score 60/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.1.8 |
| Published | 2026-02-28 |
| First published | 2024-12-19 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=18.17.0 |
| Dependencies | 6 |
| Unpacked size | 118.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | BlackGlory |
| Maintainers | black_glory |
| Keywords | dns |

## Links

- npm: https://www.npmjs.com/package/extra-dns
- Repository: https://github.com/BlackGlory/extra-dns
- Homepage: https://github.com/BlackGlory/extra-dns#readme
- Issues: https://github.com/BlackGlory/extra-dns/issues
- npm.io page: https://npm.io/package/extra-dns

## Dependencies (6)

- [justypes](https://npm.io/package/justypes.md) ^4.4.1
- [extra-abort](https://npm.io/package/extra-abort.md) ^0.4.0
- [extra-utils](https://npm.io/package/extra-utils.md) ^5.17.0
- [extra-promise](https://npm.io/package/extra-promise.md) ^7.0.0
- [@blackglory/prelude](https://npm.io/package/@blackglory/prelude.md) ^0.4.0
- [@blackglory/structures](https://npm.io/package/@blackglory/structures.md) ^0.14.9

## Recent versions

- 0.1.8 (latest) — 2026-02-28
- 0.1.7 — 2026-02-28
- 0.1.6 — 2024-12-28
- 0.1.5 — 2024-12-28
- 0.1.4 — 2024-12-28
- 0.1.3 — 2024-12-25
- 0.1.2 — 2024-12-19
- 0.1.1 — 2024-12-19
- 0.1.0 — 2024-12-19

## README

# extra-dns
## Install
```sh
npm install --save extra-dns
# or
yarn add extra-dns
```

## Usage
```ts
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
```ts
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
```ts
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
```ts
class DNSClient {
  constructor(host: string, port: number, socket?: dgram.Socket)

  close(): Promise<void>

  resolve(query: Packet, signal?: AbortSignal): Promise<Packet>
}
```

### RDATA
#### A_RDATA
```ts
class A_RDATA {
  constructor(
    public ADDRESS: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): A_RDATA
}
```

#### AAAA_RDATA
```ts
class AAAA_RDATA {
  constructor(
    public ADDRESS: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): AAAA_RDATA
}
```

#### CNAME_RDATA
```ts
class CNAME_RDATA {
  constructor(
    public CNAME: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): CNAME_RDATA
}
```

#### MX_RDATA
```ts
class MX_RDATA {
  constructor(
    public PREFERENCE: number
  , public EXCHANGE: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): MX_RDATA
}
```

#### NS_RDATA
```ts
class NS_RDATA {
  constructor(
    public NSDNAME: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): NS_RDATA
}
```

#### PTR_RDATA
```ts
class PTR_RDATA {
  constructor(
    public PTRDNAME: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): PTR_RDATA
}
```

#### SOA_RDATA
```ts
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
```ts
class AFSDB_RDATA {
  constructor(
    public SUBTYPE: number
  , public HOSTNAME: string
  )

  static decode(buffer: ArrayBufferLike, byteOffset: number): AFSDB_RDATA
}
```

#### NAPTR_RDATA
```ts
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
```ts
class SRV_RDATA {
  constructor(
    public PRIORITY: number
  , public WEIGHT: number
  , public PORT: number
  , public TARGET: string
  ) {}

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

---
_Source: https://npm.io/package/extra-dns · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
