# dns-lookup-cache

> An implementation to speed up the nodejs `dns.lookup` method by avoiding thread pool and using resolve4/resolve6 with DNS TTL values

Latest version **1.0.4** (published 2020-01-23) · MIT license · 0 weekly downloads

## Install

```sh
npm install dns-lookup-cache
pnpm add dns-lookup-cache
yarn add dns-lookup-cache
bun add dns-lookup-cache
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.4 |
| Published | 2020-01-23 |
| First published | 2018-09-17 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Node | >=6.0 |
| Dependencies | 2 |
| Unpacked size | 90.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 55 |
| Maintainers | fox_hellraiser, fxmaxvl, jangolle, lcmbot, legenage, woz |
| Keywords | dns, lookup, resolve4, resolve6, cache, ipv4, ipv6 |

## Links

- npm: https://www.npmjs.com/package/dns-lookup-cache
- Repository: https://github.com/LCMApps/dns-lookup-cache
- Issues: https://github.com/LCMApps/dns-lookup-cache/issues
- npm.io page: https://npm.io/package/dns-lookup-cache

## Dependencies (2)

- [rr](https://npm.io/package/rr.md) ^0.1.0
- [lodash](https://npm.io/package/lodash.md) ^4.17.11

## Alternatives

- [memory-cache](https://npm.io/package/memory-cache.md) — 795.0K weekly downloads
- [@httptoolkit/proxy-agent](https://npm.io/package/@httptoolkit/proxy-agent.md) — 11.2K weekly downloads
- [express-cache-controller](https://npm.io/package/express-cache-controller.md) — 5.3K weekly downloads
- [http-cache-middleware](https://npm.io/package/http-cache-middleware.md) — 4.5K weekly downloads
- [cache2](https://npm.io/package/cache2.md) — 1.5K weekly downloads

## Recent versions

- 1.0.4 (latest) — 2020-01-23
- 1.0.3 — 2018-10-30
- 1.0.2 — 2018-09-17

## README

# dns-lookup-cache - DNS cache to replace NodeJS `dns.lookup` standard method

[![NPM version](https://img.shields.io/npm/v/dns-lookup-cache.svg)](https://www.npmjs.com/package/dns-lookup-cache)
[![Release Status](https://github.com/LCMApps/lcm-requester/workflows/NPM%20Release/badge.svg)](https://github.com/LCMApps/dns-lookup-cache/releases)
[![Build Status](https://travis-ci.org/LCMApps/dns-lookup-cache.svg?branch=master)](https://travis-ci.org/LCMApps/dns-lookup-cache)
[![Coverage Status](https://coveralls.io/repos/github/LCMApps/dns-lookup-cache/badge.svg?branch=master)](https://coveralls.io/github/LCMApps/dns-lookup-cache?branch=master)

## Super simple to use

```js
const request = require('request');
const {lookup} = require('dns-lookup-cache');

// With "request" module

request({
    url: 'http://google.com',
    method: 'GET',
    lookup: lookup
}, (error, response, body) => {
    // ...
});

// Direct usage

lookup('google.com', {}, (error, address, family) => {
    // ...
});
```

## Table of contents

- [Motivation](#motivation)
- [How to use](#howtouse)
- [Inner implementation](#implementation)
- [Examples](#examples)

---

## Motivation

The main idea behind this package is eliminate NodeJS event loop usage when you do network request.
See [NodeJS DNS implementation](https://nodejs.org/api/dns.html#dns_implementation_considerations) to understand the problem with `dns.lookup`.


[back to top](#table-of-contents)

---

## How to use

This module supports almost the same params as `dns.lookup` does. Concretely, you can pass `options` object as a second param, and
set:
- `family` to `4` or `6`
- `all` flag to `true`/`false` if you want/don't want get all IP addresses at once.

Because this implementation does not use `getaddrinfo` method, the `hints` param is not supported.

The `verbatim` param is not supported for now. If you will not specify any family you will get IPv4 addresses first and IPv6 addresses second.
 
The `callback` function works the same way as a standard method.

The `error` object would have all fields the standard implementation's error object has.

NodeJS `dns.lookup`:
```javascript
> const dns = require('dns');
> dns.lookup('host-doesnot-support-ipv6', {family: 6}, console.log)

> { Error: getaddrinfo ENOTFOUND host-doesnot-support-ipv6
    at errnoException (dns.js:55:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:97:26)
  code: 'ENOTFOUND',
  errno: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'host-doesnot-support-ipv6' }

```

`dns-lookup-cache`
```javascript
> const {lookup} = require('dns-lookup-cache');
> lookup('host-doesnot-support-ipv6', {family: 6}, console.log)

> { Error: queryAaaa ENOTFOUND host-doesnot-support-ipv6
      at makeNotFoundError (/path/dns-lookup-cache/src/Lookup.js:182:19)
      at ipv6AddressesTable.resolve (/path/dns-lookup-cache/src/Lookup.js:147:37)
      at Immediate.setImmediate [as _onImmediate] (/path/dns-lookup-cache/src/IpAddressesTable.js:70:48)
      at runCallback (timers.js:773:18)
      at tryOnImmediate (timers.js:734:5)
      at processImmediate [as _immediateCallback] (timers.js:711:5)
    hostname: 'host-doesnot-support-ipv6',
    syscall: 'queryAaaa',
    code: 'ENOTFOUND',
    errno: 'ENOTFOUND' }
```

If you are looking for `IPv4` addresses only, explicitly specify param `{family: 4}`. In that case, you will avoid 
spending time on useless searching for `IPv6`. Apply the same technique if you are looking for `IPv6` addresses only. 

Under the hood, `lookup` method has Round-robin algorithm. It means that if particular hostname resolves to several addresses
it will return new address every time you call that function. For example:
```javascript
// hostname: example.com
// resolves to: [1.2.3.4, 5.6.7.8, 9.10.11.12]

lookup('example.com', {family: 4}, (error, address, family) => {
   // address === "1.2.3.4"
   // family === 4
});

lookup('example.com', {family: 4}, (error, address, family) => {
   // address === "5.6.7.8"
   // family === 4
});

lookup('example.com', {family: 4}, (error, address, family) => {
   // address === "9.10.11.12"
   // family === 4
});

lookup('example.com', {family: 4}, (error, address, family) => {
   // address === "1.2.3.4"
   // family === 4
});
```

[back to top](#table-of-contents)

---
## Implementation

Under the hood, this package uses `dns.resolve4` and `dns.resolve6` methods with `{ttl: true}` param.
It caches addresses for that particular hostname for DNS TTL time and returns one address if you specified `{all: false}` (default value)
and array of addresses if `{all: true}`.

If you didn't specify family type (`{family: 4}` or `{family: 6}`) the method searches for addresses of `{family: 4}` and `{family: 6}` in parallel.
After that, if you specified `{all: true}` it returns an array in form `[[...IPv4],[...IPv6]]`, in other case it returns `IPv4` or `IPv6` address.
(`IPv4` has more priority).

[back to top](#table-of-contents)

---
## Examples

```javascript
lookup('hostname', {all: true}, (error, results) => {
   // results is an array that contains both IPv4 and IPv6 addresses (Ipv4 first).
   //
   // error - null
   // results - [ 
   //   { address: '1.2.3.4', family: 4 },
   //   { address: '5.6.7.8', family: 4 } 
   // ]
});
```

```javascript
lookup('hostname', {all: false}, (error, address, family) => {
   // address and family of the first resolved IP (IPv4 or IPv6 if supported).
   // error - null
   // address - '1.2.3.4'
   // family - 4
});
```

```javascript
lookup('hostname', {all: false, family: 4}, (error, address, family) => {
   // address and family of the first resolved IP (IPv4 only). 
});
```

```javascript
lookup('hostname', {all: false, family: 6}, (error, address, family) => {
   // address and family of the first resolved IP (IPv6 only).
   // will return an error if IPv6 is not supported. See NodeJS dns.lookup doc.
});
```

[back to top](#table-of-contents)

---
## Similar packages

Yahoo tried to solve this problem in own way https://github.com/yahoo/dnscache.

The big disadvantages if this package are:
- monkey patching dns module
- does not support DNS TTL
- cache just one IP address and use it for every request (no advantage of round-robin if you have dns resolver that returns several addresses)

[back to top](#table-of-contents)

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