The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / lib / dns.js @ 8886c6bf

History | View | Annotate | Download (7.43 KB)

1
// Copyright Joyent, Inc. and other Node contributors.
2
//
3
// Permission is hereby granted, free of charge, to any person obtaining a
4
// copy of this software and associated documentation files (the
5
// 'Software'), to deal in the Software without restriction, including
6
// without limitation the rights to use, copy, modify, merge, publish,
7
// distribute, sublicense, and/or sell copies of the Software, and to permit
8
// persons to whom the Software is furnished to do so, subject to the
9
// following conditions:
10
//
11
// The above copyright notice and this permission notice shall be included
12
// in all copies or substantial portions of the Software.
13
//
14
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21

    
22
var cares = process.binding('cares_wrap'),
23
    net = require('net'),
24
    isIp = net.isIP;
25

    
26

    
27
function errnoException(errorno, syscall) {
28
  // TODO make this more compatible with ErrnoException from src/node.cc
29
  // Once all of Node is using this function the ErrnoException from
30
  // src/node.cc should be removed.
31

    
32
  // For backwards compatibility. libuv returns ENOENT on NXDOMAIN.
33
  if (errorno == 'ENOENT') {
34
    errorno = 'ENOTFOUND';
35
  }
36

    
37
  var e = new Error(syscall + ' ' + errorno);
38

    
39
  e.errno = e.code = errorno;
40
  e.syscall = syscall;
41
  return e;
42
}
43

    
44

    
45
// c-ares invokes a callback either synchronously or asynchronously,
46
// but the dns API should always invoke a callback asynchronously.
47
//
48
// This function makes sure that the callback is invoked asynchronously.
49
// It returns a function that invokes the callback within nextTick().
50
//
51
// To avoid invoking unnecessary nextTick(), `immediately` property of
52
// returned function should be set to true after c-ares returned.
53
//
54
// Usage:
55
//
56
// function someAPI(callback) {
57
//   callback = makeAsync(callback);
58
//   channel.someAPI(..., callback);
59
//   callback.immediately = true;
60
// }
61
function makeAsync(callback) {
62
  if (typeof callback !== 'function') {
63
    return callback;
64
  }
65
  return function asyncCallback() {
66
    if (asyncCallback.immediately) {
67
      // The API already returned, we can invoke the callback immediately.
68
      callback.apply(null, arguments);
69
    } else {
70
      var args = arguments;
71
      process.nextTick(function() {
72
        callback.apply(null, args);
73
      });
74
    }
75
  };
76
}
77

    
78

    
79
// Easy DNS A/AAAA look up
80
// lookup(domain, [family,] callback)
81
exports.lookup = function(domain, family, callback) {
82
  // parse arguments
83
  if (arguments.length === 2) {
84
    callback = family;
85
    family = 0;
86
  } else if (!family) {
87
    family = 0;
88
  } else {
89
    family = +family;
90
    if (family !== 4 && family !== 6) {
91
      throw new Error('invalid argument: `family` must be 4 or 6');
92
    }
93
  }
94
  callback = makeAsync(callback);
95

    
96
  if (!domain) {
97
    callback(null, null, family === 6 ? 6 : 4);
98
    return {};
99
  }
100

    
101
  // Hack required for Windows because Win7 removed the
102
  // localhost entry from c:\WINDOWS\system32\drivers\etc\hosts
103
  // See http://daniel.haxx.se/blog/2011/02/21/localhost-hack-on-windows/
104
  // TODO Remove this once c-ares handles this problem.
105
  if (process.platform == 'win32' && domain == 'localhost') {
106
    callback(null, '127.0.0.1', 4);
107
    return {};
108
  }
109

    
110
  var matchedFamily = net.isIP(domain);
111
  if (matchedFamily) {
112
    callback(null, domain, matchedFamily);
113
    return {};
114
  }
115

    
116
  function onanswer(addresses) {
117
    if (addresses) {
118
      if (family) {
119
        callback(null, addresses[0], family);
120
      } else {
121
        callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4);
122
      }
123
    } else {
124
      callback(errnoException(process._errno, 'getaddrinfo'));
125
    }
126
  }
127

    
128
  var wrap = cares.getaddrinfo(domain, family);
129

    
130
  if (!wrap) {
131
    throw errnoException(process._errno, 'getaddrinfo');
132
  }
133

    
134
  wrap.oncomplete = onanswer;
135

    
136
  callback.immediately = true;
137
  return wrap;
138
};
139

    
140

    
141
function resolver(bindingName) {
142
  var binding = cares[bindingName];
143

    
144
  return function query(name, callback) {
145
    function onanswer(status, result) {
146
      if (!status) {
147
        callback(null, result);
148
      } else {
149
        callback(errnoException(process._errno, bindingName));
150
      }
151
    }
152

    
153
    callback = makeAsync(callback);
154
    var wrap = binding(name, onanswer);
155
    if (!wrap) {
156
      throw errnoException(process._errno, bindingName);
157
    }
158

    
159
    callback.immediately = true;
160
    return wrap;
161
  }
162
}
163

    
164

    
165
var resolveMap = {};
166
exports.resolve4 = resolveMap.A = resolver('queryA');
167
exports.resolve6 = resolveMap.AAAA = resolver('queryAaaa');
168
exports.resolveCname = resolveMap.CNAME = resolver('queryCname');
169
exports.resolveMx = resolveMap.MX = resolver('queryMx');
170
exports.resolveNs = resolveMap.NS = resolver('queryNs');
171
exports.resolveTxt = resolveMap.TXT = resolver('queryTxt');
172
exports.resolveSrv = resolveMap.SRV = resolver('querySrv');
173
exports.resolveNaptr = resolveMap.NAPTR = resolver('queryNaptr');
174
exports.reverse = resolveMap.PTR = resolver('getHostByAddr');
175

    
176

    
177
exports.resolve = function(domain, type_, callback_) {
178
  var resolver, callback;
179
  if (typeof type_ == 'string') {
180
    resolver = resolveMap[type_];
181
    callback = callback_;
182
  } else {
183
    resolver = exports.resolve4;
184
    callback = type_;
185
  }
186

    
187
  if (typeof resolver === 'function') {
188
    return resolver(domain, callback);
189
  } else {
190
    throw new Error('Unknown type "' + type_ + '"');
191
  }
192
};
193

    
194

    
195
exports.getServers = function() {
196
  return cares.getServers();
197
};
198

    
199

    
200
exports.setServers = function(servers) {
201
  // cache the original servers because in the event of an error setting the
202
  // servers cares won't have any servers available for resolution
203
  var orig = cares.getServers();
204

    
205
  var newSet = [];
206

    
207
  servers.forEach(function(serv) {
208
    var ver = isIp(serv);
209

    
210
    if (ver)
211
      return newSet.push([ver, serv]);
212

    
213
    var match = serv.match(/\[(.*)\](:\d+)?/);
214

    
215
    // we have an IPv6 in brackets
216
    if (match) {
217
      ver = isIp(match[1]);
218
      if (ver)
219
        return newSet.push([ver, match[1]]);
220
    }
221

    
222
    var s = serv.split(/:\d+$/)[0];
223
    ver = isIp(s);
224

    
225
    if (ver)
226
      return newSet.push([ver, s]);
227

    
228
    throw new Error('IP address is not properly formatted: ' + serv);
229
  });
230

    
231
  var r = cares.setServers(newSet);
232

    
233
  if (r) {
234
    // reset the servers to the old servers, because ares probably unset them
235
    cares.setServers(orig.join(','));
236

    
237
    var err = cares.strerror(r);
238
    throw new Error('c-ares failed to set servers: "' + err +
239
                    '" [' + servers + ']');
240
  }
241
};
242

    
243

    
244
// ERROR CODES
245
exports.NODATA = 'ENODATA';
246
exports.FORMERR = 'EFORMERR';
247
exports.SERVFAIL = 'ESERVFAIL';
248
exports.NOTFOUND = 'ENOTFOUND';
249
exports.NOTIMP = 'ENOTIMP';
250
exports.REFUSED = 'EREFUSED';
251
exports.BADQUERY = 'EBADQUERY';
252
exports.ADNAME = 'EADNAME';
253
exports.BADFAMILY = 'EBADFAMILY';
254
exports.BADRESP = 'EBADRESP';
255
exports.CONNREFUSED = 'ECONNREFUSED';
256
exports.TIMEOUT = 'ETIMEOUT';
257
exports.EOF = 'EOF';
258
exports.FILE = 'EFILE';
259
exports.NOMEM = 'ENOMEM';
260
exports.DESTRUCTION = 'EDESTRUCTION';
261
exports.BADSTR = 'EBADSTR';
262
exports.BADFLAGS = 'EBADFLAGS';
263
exports.NONAME = 'ENONAME';
264
exports.BADHINTS = 'EBADHINTS';
265
exports.NOTINITIALIZED = 'ENOTINITIALIZED';
266
exports.LOADIPHLPAPI = 'ELOADIPHLPAPI';
267
exports.ADDRGETNETWORKPARAMS = 'EADDRGETNETWORKPARAMS';
268
exports.CANCELLED = 'ECANCELLED';