dns2 1.5.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "semistandard",
3
+ "rules": {
4
+ "space-before-function-paren": ["error", "never"],
5
+ "no-multi-spaces": ["error"],
6
+ "array-bracket-spacing": ["error", "always"],
7
+ "key-spacing": ["error", {
8
+ "align": {
9
+ "beforeColon": true,
10
+ "afterColon": true,
11
+ "on": "colon"
12
+ }
13
+ }],
14
+ "comma-dangle": ["error", "always-multiline"]
15
+ }
16
+ }
@@ -0,0 +1,12 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: song940
4
+ patreon: song940
5
+ open_collective: song940
6
+ ko_fi: # Replace with a single Ko-fi username
7
+ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: # Replace with a single IssueHunt username
11
+ otechie: # Replace with a single Otechie username
12
+ custom: https://git.io/fjRcB
@@ -0,0 +1,17 @@
1
+ # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2
+ # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3
+
4
+ name: Linting
5
+
6
+ on: [push, pull_request]
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - uses: actions/setup-node@v1
14
+ with:
15
+ node-version: 16
16
+ - run: npm i
17
+ - run: npm run lint
@@ -16,7 +16,7 @@ jobs:
16
16
 
17
17
  strategy:
18
18
  matrix:
19
- node-version: [10.x, 12.x, 14.x, 15.x]
19
+ node-version: [10.x, 12.x, 14.x, 16.x]
20
20
  # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21
21
 
22
22
  steps:
@@ -26,5 +26,4 @@ jobs:
26
26
  with:
27
27
  node-version: ${{ matrix.node-version }}
28
28
  - run: npm ci
29
- - run: npm run build --if-present
30
29
  - run: npm test
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # dns2
2
2
 
3
3
  ![NPM version](https://img.shields.io/npm/v/dns2.svg?style=flat)
4
- [![Build Status](https://travis-ci.org/song940/node-dns.svg?branch=master)](https://travis-ci.org/song940/node-dns)
4
+ [![Node.js CI](https://github.com/song940/node-dns/actions/workflows/node.js.yml/badge.svg)](https://github.com/song940/node-dns/actions/workflows/node.js.yml)
5
5
 
6
6
  > A DNS Server and Client Implementation in Pure JavaScript with no dependencies.
7
7
 
@@ -124,25 +124,56 @@ const dns2 = require('dns2');
124
124
 
125
125
  const { Packet } = dns2;
126
126
 
127
- const server = dns2.createUDPServer((request, send, rinfo) => {
128
- const response = Packet.createResponseFromRequest(request);
129
- const [ question ] = request.questions;
130
- const { name } = question;
131
- response.answers.push({
132
- name,
133
- type: Packet.TYPE.A,
134
- class: Packet.CLASS.IN,
135
- ttl: 300,
136
- address: '8.8.8.8'
137
- });
138
- send(response);
127
+ const server = dns2.createServer({
128
+ udp: true,
129
+ handle: (request, send, rinfo) => {
130
+ const response = Packet.createResponseFromRequest(request);
131
+ const [ question ] = request.questions;
132
+ const { name } = question;
133
+ response.answers.push({
134
+ name,
135
+ type: Packet.TYPE.A,
136
+ class: Packet.CLASS.IN,
137
+ ttl: 300,
138
+ address: '8.8.8.8'
139
+ });
140
+ send(response);
141
+ }
139
142
  });
140
143
 
141
144
  server.on('request', (request, response, rinfo) => {
142
145
  console.log(request.header.id, request.questions[0]);
143
146
  });
144
147
 
145
- server.listen(5333);
148
+ server.on('requestError', (error) => {
149
+ console.log('Client sent an invalid request', error);
150
+ });
151
+
152
+ server.on('listening', () => {
153
+ console.log(server.addresses());
154
+ });
155
+
156
+ server.on('close', () => {
157
+ console.log('server closed');
158
+ });
159
+
160
+ server.listen({
161
+ // Optionally specify port, address and/or the family of socket() for udp server:
162
+ udp: {
163
+ port: 5333,
164
+ address: "127.0.0.1",
165
+ type: "udp4", // IPv4 or IPv6 (Must be either "udp4" or "udp6")
166
+ },
167
+
168
+ // Optionally specify port and/or address for tcp server:
169
+ tcp: {
170
+ port: 5333,
171
+ address: "127.0.0.1",
172
+ },
173
+ });
174
+
175
+ // eventually
176
+ server.close();
146
177
  ```
147
178
 
148
179
  Then you can test your DNS server:
@@ -175,7 +206,7 @@ will be found in `request.questions[0].name`.
175
206
 
176
207
  ### MIT license
177
208
 
178
- Copyright (c) 2016 lsong
209
+ Copyright (c) 2016 LIU SONG <song940@gmail.com> & [contributors](https://github.com/song940/node-dns/graphs/contributors).
179
210
 
180
211
  Permission is hereby granted, free of charge, to any person obtaining a copy
181
212
  of this software and associated documentation files (the "Software"), to deal
package/client/doh.js CHANGED
@@ -1,11 +1,12 @@
1
- const https = require('https');
2
1
  const Packet = require('../packet');
3
2
 
4
- const get = url => new Promise(resolve => {
3
+ const defaultGet = url => new Promise((resolve, reject) => {
5
4
  const headers = {
6
- accept: 'application/dns-message'
5
+ accept: 'application/dns-message',
7
6
  };
8
- https.get(url, { headers }, resolve);
7
+ const base = url.startsWith('https') ? require('https') : require('http');
8
+ const req = base.get(url, { headers }, resolve);
9
+ req.on('error', reject);
9
10
  });
10
11
 
11
12
  const readStream = stream => {
@@ -13,30 +14,37 @@ const readStream = stream => {
13
14
  return new Promise((resolve, reject) => {
14
15
  stream
15
16
  .on('error', reject)
16
- .on('data', chunk => buffer.push(chunk))
17
+ .on('data', chunk => buffer.push(chunk))
17
18
  .on('end', () => resolve(Buffer.concat(buffer)));
18
- })
19
+ });
19
20
  };
20
21
 
21
22
  /**
22
23
  * @docs https://tools.ietf.org/html/rfc8484
23
- * @param {*} param0
24
+ * @param {*} param0
24
25
  */
25
- const DOHClient = ({ dns } = {}) => {
26
- return (name, type = 'A', cls = Packet.CLASS.IN) => {
26
+ const DOHClient = ({ dns, http, get = defaultGet } = {}) => {
27
+ return (name, type = 'A', cls = Packet.CLASS.IN, { clientIp, recursive = true } = {}) => {
27
28
  const packet = new Packet();
29
+ // see https://github.com/song940/node-dns/issues/29
30
+ if (recursive) {
31
+ packet.header.rd = 1;
32
+ }
33
+ if (clientIp) {
34
+ packet.additionals.push(Packet.Resource.EDNS([
35
+ Packet.Resource.EDNS.ECS(clientIp),
36
+ ]));
37
+ }
28
38
  packet.questions.push({
29
39
  name,
30
- class: cls,
31
- type: Packet.TYPE[type],
40
+ class : cls,
41
+ type : Packet.TYPE[type],
32
42
  });
33
43
  const query = packet.toBase64URL();
34
- return Promise
35
- .resolve()
36
- .then(() => get(`https://${dns}/dns-query?dns=${query}`))
44
+ return Promise.resolve(get(`http${http ? '' : 's'}://${dns}/dns-query?dns=${query}`))
37
45
  .then(readStream)
38
- .then(Packet.parse)
46
+ .then(Packet.parse);
39
47
  };
40
48
  };
41
49
 
42
- module.exports = DOHClient;
50
+ module.exports = DOHClient;
package/client/google.js CHANGED
@@ -9,19 +9,19 @@ const readStream = stream => {
9
9
  stream
10
10
  .on('error', reject)
11
11
  .on('data', chunk => {
12
- buffer.push(chunk)
12
+ buffer.push(chunk);
13
13
  })
14
14
  .on('end', () => resolve(Buffer.concat(buffer)));
15
15
  });
16
16
  };
17
17
 
18
- const GoogleClient = ({ }) =>
18
+ const GoogleClient = () =>
19
19
  (name, type = 'ANY') => {
20
20
  return Promise
21
21
  .resolve()
22
22
  .then(() => get(`https://dns.google.com/resolve?name=${name}&type=${type}`))
23
23
  .then(readStream)
24
- .then(JSON.parse)
24
+ .then(JSON.parse);
25
25
  };
26
26
 
27
- module.exports = GoogleClient;
27
+ module.exports = GoogleClient;
package/client/tcp.js CHANGED
@@ -2,33 +2,33 @@ const tcp = require('net');
2
2
  const Packet = require('../packet');
3
3
 
4
4
  module.exports = ({ dns = '1.1.1.1', port = 53 } = {}) => {
5
- return async (name, type = 'A', cls = Packet.CLASS.IN, { clientIp, recursive = true } = {}) => {
5
+ return async(name, type = 'A', cls = Packet.CLASS.IN, { clientIp, recursive = true } = {}) => {
6
6
  const packet = new Packet();
7
7
 
8
8
  // see https://github.com/song940/node-dns/issues/29
9
9
  if (recursive) {
10
- query.header.rd = 1;
10
+ packet.header.rd = 1;
11
11
  }
12
12
  if (clientIp) {
13
- query.additionals.push(Packet.Resource.EDNS([
14
- Packet.Resource.EDNS.ECS(clientIp)
13
+ packet.additionals.push(Packet.Resource.EDNS([
14
+ Packet.Resource.EDNS.ECS(clientIp),
15
15
  ]));
16
- };
16
+ }
17
17
 
18
18
  packet.questions.push({
19
19
  name,
20
- class: cls,
21
- type: Packet.TYPE[type],
20
+ class : cls,
21
+ type : Packet.TYPE[type],
22
22
  });
23
23
  const message = packet.toBuffer();
24
24
  const len = Buffer.alloc(2);
25
25
  len.writeUInt16BE(message.length);
26
26
  const client = tcp.connect({ host: dns, port });
27
- client.end(Buffer.concat([len, message]));
27
+ client.end(Buffer.concat([ len, message ]));
28
28
  const data = await Packet.readStream(client);
29
29
  if (!data.length) {
30
30
  throw new Error('Empty TCP response');
31
31
  }
32
32
  return Packet.parse(data);
33
- }
34
- };
33
+ };
34
+ };
package/client/udp.js CHANGED
@@ -16,13 +16,13 @@ module.exports = ({ dns = '8.8.8.8', port = 53, socketType = 'udp4' } = {}) => {
16
16
  }
17
17
  if (clientIp) {
18
18
  query.additionals.push(Packet.Resource.EDNS([
19
- Packet.Resource.EDNS.ECS(clientIp)
19
+ Packet.Resource.EDNS.ECS(clientIp),
20
20
  ]));
21
- };
21
+ }
22
22
  query.questions.push({
23
23
  name,
24
- class: cls,
25
- type: Packet.TYPE[type],
24
+ class : cls,
25
+ type : Packet.TYPE[type],
26
26
  });
27
27
  const client = new udp.Socket(socketType);
28
28
  return new Promise((resolve, reject) => {
@@ -35,5 +35,5 @@ module.exports = ({ dns = '8.8.8.8', port = 53, socketType = 'udp4' } = {}) => {
35
35
  debug('send', dns, query.toBuffer());
36
36
  client.send(query.toBuffer(), port, dns, err => err && reject(err));
37
37
  });
38
- }
39
- };
38
+ };
39
+ };
@@ -1,12 +1,12 @@
1
1
  const { DOHClient } = require('../..');
2
2
 
3
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
4
+
3
5
  const resolve = DOHClient({
4
- dns: '1.1.1.1'
6
+ dns: '1.1.1.1',
5
7
  });
6
8
 
7
- (async () => {
8
-
9
+ (async() => {
9
10
  const response = await resolve('google.com');
10
11
  console.log(response.answers);
11
-
12
- })();
12
+ })();
@@ -1,8 +1,7 @@
1
1
  const { GoogleClient } = require('../..');
2
2
 
3
- (async () => {
3
+ (async() => {
4
4
  const resolve = GoogleClient();
5
5
  const response = await resolve('google.com');
6
6
  console.log(response);
7
-
8
7
  })();
@@ -1,10 +1,10 @@
1
1
  const { TCPClient } = require('../..');
2
2
 
3
3
  const resolve = TCPClient({
4
- dns: '1.1.1.1'
4
+ dns: '1.1.1.1',
5
5
  });
6
6
 
7
- (async () => {
8
- const response = await resolve('google.com')
7
+ (async() => {
8
+ const response = await resolve('google.com');
9
9
  console.log(response.answers);
10
- })();
10
+ })();
@@ -2,11 +2,11 @@ const { TCPClient } = require('../..');
2
2
 
3
3
  const resolve = TCPClient();
4
4
 
5
- (async () => {
5
+ (async() => {
6
6
  try {
7
- const response = await resolve('google.com')
7
+ const response = await resolve('google.com');
8
8
  console.log(response.answers);
9
- } catch(error) {
9
+ } catch (error) {
10
10
  console.log(error);
11
11
  }
12
- })();
12
+ })();
@@ -2,10 +2,10 @@ const dns = require('dns');
2
2
  const { UDPClient } = require('../..');
3
3
 
4
4
  const resolve = UDPClient({
5
- dns: dns.getServers()[0]
5
+ dns: dns.getServers()[0],
6
6
  });
7
7
 
8
- (async () => {
9
- const response = await resolve('google.com')
8
+ (async() => {
9
+ const response = await resolve('google.com');
10
10
  console.log(response.answers);
11
- })();
11
+ })();
@@ -2,7 +2,7 @@ const DNS = require('../..');
2
2
 
3
3
  const dns = new DNS();
4
4
 
5
- (async () => {
5
+ (async() => {
6
6
  const result = await dns.resolveA('google.com');
7
7
  console.log(result.answers);
8
- })();
8
+ })();
@@ -1,9 +1,9 @@
1
1
  const DNS = require('../..');
2
2
 
3
3
  // Lookup directly from ns1.google.com
4
- const dns = new DNS({nameServers: ['216.239.32.10']});
4
+ const dns = new DNS({ nameServers: [ '216.239.32.10' ] });
5
5
 
6
- (async () => {
6
+ (async() => {
7
7
  // What is the IP address for google.com if a client in the subnet
8
8
  // '178.67.222.0/24' asks for it?
9
9
  const result = await dns.resolveA('google.com', '178.67.222.0/24');
@@ -2,7 +2,7 @@ const { UDPClient } = require('../..');
2
2
 
3
3
  const resolve = UDPClient();
4
4
 
5
- (async () => {
6
- const response = await resolve('google.com')
5
+ (async() => {
6
+ const response = await resolve('google.com');
7
7
  console.log(response.answers);
8
- })();
8
+ })();
@@ -0,0 +1,46 @@
1
+ const dns = require('../..');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+
5
+ const { Packet } = dns;
6
+
7
+ // Create a SSL enabled server
8
+ const server = dns.createServer({
9
+ udp : true,
10
+ tcp : true,
11
+ doh : {
12
+ ssl : true,
13
+ cert : fs.readFileSync(path.join(__dirname, 'server.crt')),
14
+ key : fs.readFileSync(path.join(__dirname, 'secret.key')),
15
+ },
16
+ });
17
+
18
+ // Handle the incomming request (same style as both UDP and TCP server)
19
+ server.on('request', (request, send, client) => {
20
+ const response = Packet.createResponseFromRequest(request);
21
+ const [ question ] = request.questions;
22
+ const { name } = question;
23
+ response.answers.push({
24
+ name,
25
+ type : Packet.TYPE.A,
26
+ class : Packet.CLASS.IN,
27
+ ttl : 300,
28
+ address : '1.1.1.1',
29
+ });
30
+ send(response);
31
+ });
32
+
33
+ (async() => {
34
+ const closed = new Promise(resolve => process.on('SIGINT', resolve));
35
+ await server.listen({
36
+ doh : 8443,
37
+ udp : 5333,
38
+ tcp : 5334,
39
+ });
40
+ console.log('Listening.');
41
+ console.log(server.addresses());
42
+ await closed;
43
+ process.stdout.write('\n');
44
+ await server.close();
45
+ console.log('Closed.');
46
+ })();
@@ -6,23 +6,25 @@ const { Packet } = dns;
6
6
 
7
7
  // Create a SSL enabled server
8
8
  const server = dns.createDOHServer({
9
- port: 0,
10
- sslport: 443,
11
- cert: fs.readFileSync(path.join(__dirname,"server.crt")),
12
- key: fs.readFileSync(path.join(__dirname,"secret.key"))
9
+ port : 8080,
10
+ ssl : true,
11
+ cert : fs.readFileSync(path.join(__dirname, 'server.crt')),
12
+ key : fs.readFileSync(path.join(__dirname, 'secret.key')),
13
13
  });
14
14
 
15
- //Handle the incomming request (same style as both UDP and TCP server)
15
+ // Handle the incomming request (same style as both UDP and TCP server)
16
16
  server.on('request', (request, send, client) => {
17
- const response = Packet.createResponseFromRequest(request);
18
- const [ question ] = request.questions;
19
- const { name } = question;
20
- response.answers.push({
21
- name,
22
- type: Packet.TYPE.A,
23
- class: Packet.CLASS.IN,
24
- ttl: 300,
25
- address: '8.8.8.8'
26
- });
27
- send(response);
17
+ const response = Packet.createResponseFromRequest(request);
18
+ const [ question ] = request.questions;
19
+ const { name } = question;
20
+ response.answers.push({
21
+ name,
22
+ type : Packet.TYPE.A,
23
+ class : Packet.CLASS.IN,
24
+ ttl : 300,
25
+ address : '1.1.1.1',
28
26
  });
27
+ send(response);
28
+ });
29
+
30
+ server.listen();
@@ -6,14 +6,14 @@ const server = dns.createTCPServer();
6
6
 
7
7
  server.on('request', (request, send, client) => {
8
8
  const response = Packet.createResponseFromRequest(request);
9
- const answer = new Packet.createResourceFromQuestion(request.questions[0], {
10
- target: 'hermes2.jabber.org',
11
- port: 8080,
12
- weight: 30,
13
- priority: 30
9
+ const answer = Packet.createResourceFromQuestion(request.questions[0], {
10
+ target : 'hermes2.jabber.org',
11
+ port : 8080,
12
+ weight : 30,
13
+ priority : 30,
14
14
  });
15
15
  response.answers.push(answer);
16
16
  send(response);
17
17
  });
18
18
 
19
- server.listen(5333);
19
+ server.listen(5333);
@@ -8,10 +8,10 @@ const server = dns.createUDPServer((request, send, rinfo) => {
8
8
  const { name } = question;
9
9
  response.answers.push({
10
10
  name,
11
- type: Packet.TYPE.A,
12
- class: Packet.CLASS.IN,
13
- ttl: 300,
14
- address: '8.8.8.8'
11
+ type : Packet.TYPE.A,
12
+ class : Packet.CLASS.IN,
13
+ ttl : 300,
14
+ address : '8.8.8.8',
15
15
  });
16
16
  send(response);
17
17
  });
package/index.js CHANGED
@@ -5,6 +5,7 @@ const {
5
5
  createTCPServer,
6
6
  createUDPServer,
7
7
  createDOHServer,
8
+ createServer,
8
9
  } = require('./server');
9
10
  const EventEmitter = require('events');
10
11
 
@@ -17,24 +18,25 @@ class DNS extends EventEmitter {
17
18
  constructor(options) {
18
19
  super();
19
20
  Object.assign(this, {
20
- port: 53,
21
- retries: 3,
22
- timeout: 3,
23
- recursive: true,
24
- resolverProtocol: 'UDP',
25
- nameServers: [
21
+ port : 53,
22
+ retries : 3,
23
+ timeout : 3,
24
+ recursive : true,
25
+ resolverProtocol : 'UDP',
26
+ nameServers : [
26
27
  '8.8.8.8',
27
28
  '114.114.114.114',
28
29
  ],
29
30
  rootServers: [
30
31
  'a', 'b', 'c', 'd', 'e', 'f',
31
- 'g', 'h', 'i', 'j', 'k', 'l', 'm'
32
- ].map(x => `${x}.root-servers.net`)
32
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm',
33
+ ].map(x => `${x}.root-servers.net`),
33
34
  }, options);
34
35
  }
36
+
35
37
  /**
36
38
  * query
37
- * @param {*} questions
39
+ * @param {*} questions
38
40
  */
39
41
  query(name, type, cls, clientIp) {
40
42
  const { port, nameServers, recursive, resolverProtocol = 'UDP' } = this;
@@ -44,27 +46,33 @@ class DNS extends EventEmitter {
44
46
  return resolve(name, type, cls, clientIp);
45
47
  }));
46
48
  }
49
+
47
50
  /**
48
51
  * resolve
49
- * @param {*} domain
50
- * @param {*} type
51
- * @param {*} cls
52
+ * @param {*} domain
53
+ * @param {*} type
54
+ * @param {*} cls
52
55
  */
53
- resolve(domain, type = 'ANY', cls = DNS.Packet.CLASS.IN, clientIp) {
56
+ resolve(domain, type = 'ANY', cls = DNS.Packet.CLASS.IN, clientIp = undefined) {
54
57
  return this.query(domain, type, cls, clientIp);
55
58
  }
59
+
56
60
  resolveA(domain, clientIp) {
57
61
  return this.resolve(domain, 'A', undefined, clientIp);
58
62
  }
63
+
59
64
  resolveAAAA(domain) {
60
65
  return this.resolve(domain, 'AAAA');
61
66
  }
67
+
62
68
  resolveMX(domain) {
63
69
  return this.resolve(domain, 'MX');
64
70
  }
71
+
65
72
  resolveCNAME(domain) {
66
73
  return this.resolve(domain, 'CNAME');
67
74
  }
75
+
68
76
  resolvePTR(domain) {
69
77
  return this.resolve(domain, 'PTR');
70
78
  }
@@ -77,6 +85,7 @@ DNS.DOHServer = DOHServer;
77
85
  DNS.createUDPServer = createUDPServer;
78
86
  DNS.createTCPServer = createTCPServer;
79
87
  DNS.createDOHServer = createDOHServer;
88
+ DNS.createServer = createServer;
80
89
 
81
90
  DNS.TCPClient = require('./client/tcp');
82
91
  DNS.DOHClient = require('./client/doh');
@@ -86,4 +95,3 @@ DNS.GoogleClient = require('./client/google');
86
95
  DNS.Packet = require('./packet');
87
96
 
88
97
  module.exports = DNS;
89
-