1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | "use strict";
|
24 |
|
25 | var 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 |
|
32 | var 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 | };
|
94 | exports.resolve = resolve;
|
95 |
|
96 | var resolve4 = function (domain, callback) {
|
97 | return resolve(domain, 'A', function (err, results) {
|
98 | callback(err, results);
|
99 | });
|
100 | };
|
101 | exports.resolve4 = resolve4;
|
102 |
|
103 | var resolve6 = function (domain, callback) {
|
104 | return resolve(domain, 'AAAA', function (err, results) {
|
105 | callback(err, results);
|
106 | });
|
107 | };
|
108 | exports.resolve6 = resolve6;
|
109 |
|
110 | var resolveMx = function (domain, callback) {
|
111 | return resolve(domain, 'MX', function (err, results) {
|
112 | callback(err, results);
|
113 | });
|
114 | };
|
115 | exports.resolveMx = resolveMx;
|
116 |
|
117 | var resolveTxt = function (domain, callback) {
|
118 | return resolve(domain, 'TXT', function (err, results) {
|
119 | callback(err, results);
|
120 | });
|
121 | };
|
122 | exports.resolveTxt = resolveTxt;
|
123 |
|
124 | var resolveSrv = function (domain, callback) {
|
125 | return resolve(domain, 'SRV', function (err, results) {
|
126 | callback(err, results);
|
127 | });
|
128 | };
|
129 | exports.resolveSrv = resolveSrv;
|
130 |
|
131 | var resolveNs = function (domain, callback) {
|
132 | return resolve(domain, 'NS', function (err, results) {
|
133 | callback(err, results);
|
134 | });
|
135 | };
|
136 | exports.resolveNs = resolveNs;
|
137 |
|
138 | var resolveCname = function (domain, callback) {
|
139 | return resolve(domain, 'CNAME', function (err, results) {
|
140 | callback(err, results);
|
141 | });
|
142 | };
|
143 | exports.resolveCname = resolveCname;
|
144 |
|
145 | var 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 | };
|
183 | exports.reverse = reverse;
|
184 |
|
185 | var 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 |
|
209 |
|
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 |
|
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 | };
|
253 | exports.lookup = lookup;
|