UNPKG

6.32 kBJavaScriptView Raw
1/*
2Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.com>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
21*/
22
23"use strict";
24
25var ipaddr = require('ipaddr.js'),
26 net = require('net'),
27 consts = require('./consts'),
28 types = require('./types'),
29 Packet = require('./packet'),
30 Resolve = require('./resolve');
31
32var resolve = function (domain) {
33 var rrtype = consts.NAME_TO_QTYPE.A,
34 callback = arguments[arguments.length - 1];
35
36 if (arguments.length >= 3) {
37 rrtype = consts.NAME_TO_QTYPE[arguments[1]];
38 }
39
40 var opts = {
41 domain: domain,
42 rrtype: rrtype,
43 check_hosts: false,
44 };
45
46 return new Resolve(opts, function (err, response) {
47 var ret = [], i, a;
48
49 if (err) {
50 callback(err, response);
51 return;
52 }
53
54 for (i = 0; i < response.answer.length; i++) {
55 a = response.answer[i];
56 if (a.type === rrtype) {
57 a = a.promote();
58 switch (rrtype) {
59 case consts.NAME_TO_QTYPE.A:
60 case consts.NAME_TO_QTYPE.AAAA:
61 ret.push(a.address);
62 break;
63 case consts.NAME_TO_QTYPE.MX:
64 ret.push({
65 priority: a.priority,
66 exchange: a.exchange,
67 });
68 break;
69 case consts.NAME_TO_QTYPE.TXT:
70 case consts.NAME_TO_QTYPE.NS:
71 case consts.NAME_TO_QTYPE.CNAME:
72 case consts.NAME_TO_QTYPE.PTR:
73 ret.push(a.data);
74 break;
75 case consts.NAME_TO_QTYPE.SRV:
76 ret.push({
77 priority: a.priority,
78 weight: a.weight,
79 port: a.port,
80 name: a.target,
81 });
82 break;
83 }
84 }
85 }
86
87 if (ret.length === 0) {
88 err = consts.NODATA;
89 ret = undefined;
90 }
91 callback(err, ret);
92 });
93};
94exports.resolve = resolve;
95
96var resolve4 = function (domain, callback) {
97 return resolve(domain, 'A', function (err, results) {
98 callback(err, results);
99 });
100};
101exports.resolve4 = resolve4;
102
103var resolve6 = function (domain, callback) {
104 return resolve(domain, 'AAAA', function (err, results) {
105 callback(err, results);
106 });
107};
108exports.resolve6 = resolve6;
109
110var resolveMx = function (domain, callback) {
111 return resolve(domain, 'MX', function (err, results) {
112 callback(err, results);
113 });
114};
115exports.resolveMx = resolveMx;
116
117var resolveTxt = function (domain, callback) {
118 return resolve(domain, 'TXT', function (err, results) {
119 callback(err, results);
120 });
121};
122exports.resolveTxt = resolveTxt;
123
124var resolveSrv = function (domain, callback) {
125 return resolve(domain, 'SRV', function (err, results) {
126 callback(err, results);
127 });
128};
129exports.resolveSrv = resolveSrv;
130
131var resolveNs = function (domain, callback) {
132 return resolve(domain, 'NS', function (err, results) {
133 callback(err, results);
134 });
135};
136exports.resolveNs = resolveNs;
137
138var resolveCname = function (domain, callback) {
139 return resolve(domain, 'CNAME', function (err, results) {
140 callback(err, results);
141 });
142};
143exports.resolveCname = resolveCname;
144
145var reverse = function (ip, callback) {
146 var reverseip, address, parts, kind, error;
147
148 if (!net.isIP(ip)) {
149 error = new Error("getHostByAddr ENOTIMP");
150 error.errno = 'ENOTIMP';
151 throw error;
152 }
153
154 address = ipaddr.parse(ip);
155 kind = address.kind();
156
157 switch (kind) {
158 case 'ipv4':
159 address = address.toByteArray();
160 address.reverse();
161 reverseip = address.join('.') + '.IN-ADDR.ARPA';
162 break;
163 case 'ipv6':
164 parts = [];
165 address.toNormalizedString().split(':').forEach(function (part) {
166 var i, pad = 4 - part.length;
167 for (i = 0; i < pad; i++) {
168 part = '0' + part;
169 }
170 part.split('').forEach(function (p) {
171 parts.push(p);
172 });
173 });
174 parts.reverse();
175 reverseip = parts.join('.') + '.IP6.ARPA';
176 break;
177 }
178
179 return resolve(reverseip, 'PTR', function (err, results) {
180 callback(err, results);
181 });
182};
183exports.reverse = reverse;
184
185var lookup = function (domain) {
186 var callback = arguments[arguments.length - 1],
187 family,
188 rrtype;
189
190 family = net.isIP(domain);
191
192 if (family === 4 || family === 6) {
193 callback(null, domain, family);
194 return {};
195 }
196
197 family = 4;
198
199 if (domain === null) {
200 callback(null, null, family);
201 return {};
202 }
203
204 if (arguments.length === 3) {
205 family = arguments['1'];
206 }
207 rrtype = consts.FAMILY_TO_QTYPE[family];
208 //} else {
209 // rrtype = consts.NAME_TO_QTYPE.ANY;
210 //}
211
212 var opts = {
213 domain: domain,
214 rrtype: rrtype,
215 check_hosts: true,
216 specific_server: undefined,
217 };
218
219 return new Resolve(opts, function (err, response) {
220 var i, afamily, address, a, all;
221
222 if (err) {
223 callback(err, null, 4);
224 return;
225 }
226
227 if (response instanceof Packet) {
228 all = response.answer;
229
230 //if (rrtype === consts.NAME_TO_QTYPE.ANY) {
231 all = all.concat(response.additional);
232 //}
233
234 all.forEach(function (a) {
235 if (afamily && address) {
236 return;
237 }
238 switch (a.type) {
239 case consts.NAME_TO_QTYPE.A:
240 case consts.NAME_TO_QTYPE.AAAA:
241 afamily = consts.QTYPE_TO_FAMILY[a.type];
242 address = a.promote().address;
243 break;
244 }
245 });
246 } else {
247 afamily = net.isIP(response[0]);
248 address = response[0];
249 }
250 callback(err, address, afamily);
251 });
252};
253exports.lookup = lookup;