From 58e892dadd4a93da74fca40a4d0b4d57fd5ce0fb Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Tue, 11 Oct 2011 13:21:30 -0700 Subject: [PATCH] Remove dns_legacy --- lib/{dns_uv.js => dns.js} | 0 lib/dns_legacy.js | 324 --------------- node.gyp | 4 +- src/node.cc | 1 - src/node.js | 3 - src/node_cares.cc | 814 -------------------------------------- src/node_cares.h | 37 -- src/node_extensions.h | 3 - wscript | 1 - 9 files changed, 1 insertion(+), 1186 deletions(-) rename lib/{dns_uv.js => dns.js} (100%) delete mode 100644 lib/dns_legacy.js delete mode 100644 src/node_cares.cc delete mode 100644 src/node_cares.h diff --git a/lib/dns_uv.js b/lib/dns.js similarity index 100% rename from lib/dns_uv.js rename to lib/dns.js diff --git a/lib/dns_legacy.js b/lib/dns_legacy.js deleted file mode 100644 index 1a71bf49440..00000000000 --- a/lib/dns_legacy.js +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var dns = process.binding('cares'); -var net = process.binding('net'); -var IOWatcher = process.binding('io_watcher').IOWatcher; - - -var watchers = {}; -var activeWatchers = {}; -var Timer = process.binding('timer').Timer; - -var timer = new Timer(); - -timer.ontimeout = function() { - var sockets = Object.keys(activeWatchers); - for (var i = 0, l = sockets.length; i < l; i++) { - var socket = sockets[i]; - var s = parseInt(socket, 10); - channel.processFD(watchers[socket].read ? s : dns.SOCKET_BAD, - watchers[socket].write ? s : dns.SOCKET_BAD); - } - updateTimer(); -}; - - -function updateTimer() { - timer.stop(); - - // Were just checking to see if activeWatchers is empty or not - if (0 === Object.keys(activeWatchers).length) return; - var max = 20000; - var timeout = channel.timeout(max); - timer.start(timeout, 0); -} - - -var channel = new dns.Channel({SOCK_STATE_CB: function(socket, read, write) { - var watcher, fd; - - if (process.platform == 'win32') { - fd = process.binding('os').openOSHandle(socket); - } else { - fd = socket; - } - - if (socket in watchers) { - watcher = watchers[socket].watcher; - } else { - watcher = new IOWatcher(); - watchers[socket] = { read: read, - write: write, - watcher: watcher }; - - watcher.callback = function(read, write) { - channel.processFD(read ? socket : dns.SOCKET_BAD, - write ? socket : dns.SOCKET_BAD); - updateTimer(); - }; - } - - watcher.stop(); - - if (!(read || write)) { - delete activeWatchers[socket]; - return; - } else { - watcher.set(fd, read == 1, write == 1); - watcher.start(); - activeWatchers[socket] = watcher; - } - - updateTimer(); -}}); - -// c-ares invokes a callback either synchronously or asynchronously, -// but the dns API should always invoke a callback asynchronously. -// -// This function makes sure that the callback is invoked asynchronously. -// It returns a function that invokes the callback within nextTick(). -// -// To avoid invoking unnecessary nextTick(), `immediately` property of -// returned function should be set to true after c-ares returned. -// -// Usage: -// -// function someAPI(callback) { -// callback = makeAsync(callback); -// channel.someAPI(..., callback); -// callback.immediately = true; -// } -function makeAsync(callback) { - if (typeof callback !== 'function') { - return callback; - } - return function asyncCallback() { - if (asyncCallback.immediately) { - // The API already returned, we can invoke the callback immediately. - callback.apply(null, arguments); - } else { - var args = arguments; - process.nextTick(function() { - callback.apply(null, args); - }); - } - }; -} - - -exports.resolve = function(domain, type_, callback_) { - var type, callback; - if (typeof(type_) == 'string') { - type = type_; - callback = callback_; - } else { - type = 'A'; - callback = arguments[1]; - } - - var resolveFunc = resolveMap[type]; - - if (typeof(resolveFunc) == 'function') { - resolveFunc(domain, callback); - } else { - throw new Error('Unknown type "' + type + '"'); - } -}; - - -function familyToSym(family) { - if (family !== dns.AF_INET && family !== dns.AF_INET6) { - family = (family === 6) ? dns.AF_INET6 : dns.AF_INET; - } - return family; -} - - -exports.getHostByName = function(domain, family/*=4*/, callback) { - if (typeof family === 'function') { callback = family; family = null; } - callback = makeAsync(callback); - channel.getHostByName(domain, familyToSym(family), callback); - callback.immediately = true; -}; - - -exports.getHostByAddr = function(address, family/*=4*/, callback) { - if (typeof family === 'function') { callback = family; family = null; } - callback = makeAsync(callback); - channel.getHostByAddr(address, familyToSym(family), callback); - callback.immediately = true; -}; - - -// Easy DNS A/AAAA look up -// lookup(domain, [family,] callback) -exports.lookup = function(domain, family, callback) { - // parse arguments - if (arguments.length === 2) { - callback = family; - family = undefined; - } else if (family && family !== 4 && family !== 6) { - family = parseInt(family, 10); - if (family === dns.AF_INET) { - family = 4; - } else if (family === dns.AF_INET6) { - family = 6; - } else if (family !== 4 && family !== 6) { - throw new Error('invalid argument: "family" must be 4 or 6'); - } - } - callback = makeAsync(callback); - - if (!domain) { - callback(null, null, family === 6 ? 6 : 4); - return; - } - - var matchedFamily = net.isIP(domain); - if (matchedFamily) { - callback(null, domain, matchedFamily); - return; - } - - if (/\w\.local\.?$/.test(domain)) { - // ANNOYING: In the case of mDNS domains use NSS in the thread pool. - // I wish c-ares had better support. - process.binding('net').getaddrinfo(domain, 4, function(err, domains4) { - callback(err, domains4[0], 4); - }); - callback.immediately = true; - return; - } - - if (family) { - // resolve names for explicit address family - var af = familyToSym(family); - channel.getHostByName(domain, af, function(err, domains) { - if (!err && domains && domains.length) { - if (family !== net.isIP(domains[0])) { - callback(new Error('not found'), []); - } else { - callback(null, domains[0], family); - } - } else { - callback(err, []); - } - }); - callback.immediately = true; - return; - } - - // first resolve names for v4 and if that fails, try v6 - channel.getHostByName(domain, dns.AF_INET, function(err, domains4) { - if (domains4 && domains4.length) { - callback(null, domains4[0], 4); - } else { - channel.getHostByName(domain, dns.AF_INET6, function(err, domains6) { - if (domains6 && domains6.length) { - callback(null, domains6[0], 6); - } else { - callback(err, []); - } - }); - } - }); - callback.immediately = true; -}; - - -exports.resolve4 = function(domain, callback) { - callback = makeAsync(callback); - channel.query(domain, dns.A, callback); - callback.immediately = true; -}; - - -exports.resolve6 = function(domain, callback) { - callback = makeAsync(callback); - channel.query(domain, dns.AAAA, callback); - callback.immediately = true; -}; - - -exports.resolveMx = function(domain, callback) { - callback = makeAsync(callback); - channel.query(domain, dns.MX, callback); - callback.immediately = true; -}; - - -exports.resolveTxt = function(domain, callback) { - callback = makeAsync(callback); - channel.query(domain, dns.TXT, callback); - callback.immediately = true; -}; - - -exports.resolveSrv = function(domain, callback) { - callback = makeAsync(callback); - channel.query(domain, dns.SRV, callback); - callback.immediately = true; -}; - - -exports.reverse = function(domain, callback) { - callback = makeAsync(callback); - channel.query(domain, dns.PTR, callback); - callback.immediately = true; -}; - - -exports.resolveNs = function(domain, callback) { - callback = makeAsync(callback); - channel.query(domain, dns.NS, callback); - callback.immediately = true; -}; - - -exports.resolveCname = function(domain, callback) { - callback = makeAsync(callback); - channel.query(domain, dns.CNAME, callback); - callback.immediately = true; -}; - -var resolveMap = { A: exports.resolve4, - AAAA: exports.resolve6, - MX: exports.resolveMx, - TXT: exports.resolveTxt, - SRV: exports.resolveSrv, - PTR: exports.reverse, - NS: exports.resolveNs, - CNAME: exports.resolveCname }; - -// ERROR CODES -exports.NODATA = dns.NODATA; -exports.FORMERR = dns.FORMERR; -exports.BADRESP = dns.BADRESP; -exports.NOTFOUND = dns.NOTFOUND; -exports.BADNAME = dns.BADNAME; -exports.TIMEOUT = dns.TIMEOUT; -exports.CONNREFUSED = dns.CONNREFUSED; -exports.NOMEM = dns.NOMEM; -exports.DESTRUCTION = dns.DESTRUCTION; -exports.NOTIMP = dns.NOTIMP; -exports.EREFUSED = dns.EREFUSED; -exports.SERVFAIL = dns.SERVFAIL; diff --git a/node.gyp b/node.gyp index 5f85101d8bf..88ada216e01 100644 --- a/node.gyp +++ b/node.gyp @@ -21,8 +21,7 @@ 'lib/crypto.js', 'lib/dgram_legacy.js', 'lib/dgram_uv.js', - 'lib/dns_legacy.js', - 'lib/dns_uv.js', + 'lib/dns.js', 'lib/events.js', 'lib/freelist.js', 'lib/fs.js', @@ -168,7 +167,6 @@ },{ # POSIX 'defines': [ '__POSIX__' ], 'sources': [ - 'src/node_cares.cc', 'src/node_signal_watcher.cc', 'src/node_stat_watcher.cc', 'src/node_io_watcher.cc', diff --git a/src/node.cc b/src/node.cc index e7bd4ccd3c1..e5bdd3564ab 100644 --- a/src/node.cc +++ b/src/node.cc @@ -77,7 +77,6 @@ extern "C" { #ifdef __POSIX__ # include #endif -#include #include #include #ifdef __POSIX__ diff --git a/src/node.js b/src/node.js index 427d05cdb15..3c69eabbffd 100644 --- a/src/node.js +++ b/src/node.js @@ -464,9 +464,6 @@ case 'dgram': return process.features.uv ? 'dgram_uv' : 'dgram_legacy'; - case 'dns': - return process.features.uv ? 'dns_uv' : 'dns_legacy'; - default: return id; } diff --git a/src/node_cares.cc b/src/node_cares.cc deleted file mode 100644 index 327fbd46787..00000000000 --- a/src/node_cares.cc +++ /dev/null @@ -1,814 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -#include - -#include -#include -#include - -#include - -#ifdef __POSIX__ -# include -# include - -# include -# include -#endif - -#ifdef __MINGW32__ -# include -#endif - -#ifdef __OpenBSD__ -# ifndef ns_t_a -# include -# endif -#endif // __OpenBSD__ - -/* - * HACK to use inet_pton/inet_ntop from c-ares because mingw32 doesn't have it - * This trick is used in node_net.cc as well - * TODO fixme - */ -#ifdef __MINGW32__ - extern "C" { -# include -# include - } - -# define inet_pton ares_inet_pton -# define inet_ntop ares_inet_ntop -#endif - -namespace node { - -using namespace v8; - - -class Channel : public ObjectWrap { - public: - static void Initialize(Handle target); - - private: - static Persistent constructor_template; - - static Handle New(const Arguments& args); - static Handle Query(const Arguments& args); - static Handle GetHostByName(const Arguments& args); - static Handle GetHostByAddr(const Arguments& args); - static Handle Timeout(const Arguments& args); - static Handle ProcessFD(const Arguments& args); - - ares_channel channel; - - static void SockStateCb(void *data, ares_socket_t sock, int read, int write); - static void QueryCb(void *arg, int status, int timeouts, unsigned char* abuf, int alen); -}; - - -// To be passed to the QueryCb callback when a Query is finished. -// Holds a C callback to parse the response and the final JS callback -struct QueryArg { - typedef void (*ParseAnswerCb)(QueryArg*, unsigned char*, int); - Persistent js_cb; - ParseAnswerCb parse_cb; - - QueryArg(const Local &js_cb, ParseAnswerCb parse_cb) - : js_cb(Persistent::New(Local::Cast(js_cb))) - , parse_cb(parse_cb) {} - - ~QueryArg() { - js_cb.Dispose(); - } -}; - - -Persistent Channel::constructor_template; -static Persistent priority_symbol; -static Persistent weight_symbol; -static Persistent port_symbol; -static Persistent name_symbol; -static Persistent callback_symbol; -static Persistent exchange_symbol; - - -void Cares::Initialize(Handle target) { - HandleScope scope; - - int r = ares_library_init(ARES_LIB_INIT_ALL); - if (0 != r) { - // TODO - // ThrowException(Exception::Error(String::New(ares_strerror(r)))); - assert(r == 0); - } - - - target->Set(String::NewSymbol("SOCKET_BAD"), Integer::New(ARES_SOCKET_BAD)); - - priority_symbol = NODE_PSYMBOL("priority"); - weight_symbol = NODE_PSYMBOL("weight"); - port_symbol = NODE_PSYMBOL("port"); - name_symbol = NODE_PSYMBOL("name"); - exchange_symbol = NODE_PSYMBOL("exchange"); - - target->Set(String::NewSymbol("AF_INET"), Integer::New(AF_INET)); - target->Set(String::NewSymbol("AF_INET6"), Integer::New(AF_INET6)); - - target->Set(String::NewSymbol("A"), Integer::New(ns_t_a)); - target->Set(String::NewSymbol("AAAA"), Integer::New(ns_t_aaaa)); - target->Set(String::NewSymbol("MX"), Integer::New(ns_t_mx)); - target->Set(String::NewSymbol("NS"), Integer::New(ns_t_ns)); - target->Set(String::NewSymbol("PTR"), Integer::New(ns_t_ptr)); - target->Set(String::NewSymbol("TXT"), Integer::New(ns_t_txt)); - target->Set(String::NewSymbol("SRV"), Integer::New(ns_t_srv)); - target->Set(String::NewSymbol("CNAME"), Integer::New(ns_t_cname)); - - target->Set(String::NewSymbol("NODATA"), Integer::New(ARES_ENODATA)); - target->Set(String::NewSymbol("FORMERR"), Integer::New(ARES_EFORMERR)); - target->Set(String::NewSymbol("BADRESP"), Integer::New(ARES_EBADRESP)); - target->Set(String::NewSymbol("NOTFOUND"), Integer::New(ARES_ENOTFOUND)); - target->Set(String::NewSymbol("BADNAME"), Integer::New(ARES_EBADNAME)); - target->Set(String::NewSymbol("TIMEOUT"), Integer::New(ARES_ETIMEOUT)); - target->Set(String::NewSymbol("CONNREFUSED"), Integer::New(ARES_ECONNREFUSED)); - target->Set(String::NewSymbol("NOMEM"), Integer::New(ARES_ENOMEM)); - target->Set(String::NewSymbol("DESTRUCTION"), Integer::New(ARES_EDESTRUCTION)); - - // Only occur if the ARES_FLAG_NOCHECKRESP flag was specified - target->Set(String::NewSymbol("NOTIMP"), Integer::New(ARES_ENOTIMP)); - target->Set(String::NewSymbol("EREFUSED"), Integer::New(ARES_EREFUSED)); - target->Set(String::NewSymbol("SERVFAIL"), Integer::New(ARES_ESERVFAIL)); - - Channel::Initialize(target); -} - - -static Local HostEntToAddresses(struct hostent* hostent) { - Local addresses = Array::New(); - - - char ip[INET6_ADDRSTRLEN]; - for (int i = 0; hostent->h_addr_list[i]; ++i) { - inet_ntop(hostent->h_addrtype, hostent->h_addr_list[i], ip, sizeof(ip)); - - Local address = String::New(ip); - addresses->Set(Integer::New(i), address); - } - - return addresses; -} - - -static Local HostEntToNames(struct hostent* hostent) { - Local names = Array::New(); - - for (int i = 0; hostent->h_aliases[i]; ++i) { - Local address = String::New(hostent->h_aliases[i]); - names->Set(Integer::New(i), address); - } - - return names; -} - -static inline const char *ares_errno_string(int errorno) { -#define ERRNO_CASE(e) case ARES_##e: return #e; - switch (errorno) { - ERRNO_CASE(SUCCESS) - ERRNO_CASE(ENODATA) - ERRNO_CASE(EFORMERR) - ERRNO_CASE(ESERVFAIL) - ERRNO_CASE(ENOTFOUND) - ERRNO_CASE(ENOTIMP) - ERRNO_CASE(EREFUSED) - ERRNO_CASE(EBADQUERY) - ERRNO_CASE(EBADNAME) - ERRNO_CASE(EBADFAMILY) - ERRNO_CASE(EBADRESP) - ERRNO_CASE(ECONNREFUSED) - ERRNO_CASE(ETIMEOUT) - ERRNO_CASE(EOF) - ERRNO_CASE(EFILE) - ERRNO_CASE(ENOMEM) - ERRNO_CASE(EDESTRUCTION) - ERRNO_CASE(EBADSTR) - ERRNO_CASE(EBADFLAGS) - ERRNO_CASE(ENONAME) - ERRNO_CASE(EBADHINTS) - ERRNO_CASE(ENOTINITIALIZED) - ERRNO_CASE(ELOADIPHLPAPI) - ERRNO_CASE(EADDRGETNETWORKPARAMS) - ERRNO_CASE(ECANCELLED) - default: - assert(0 && "Unhandled c-ares errno"); - return "(UNKNOWN)"; - } -} - - -static void ResolveError(Persistent &cb, int status) { - HandleScope scope; - - Local code = String::NewSymbol(ares_errno_string(status)); - Local message = String::NewSymbol(ares_strerror(status)); - - Local cons1 = String::Concat(code, String::NewSymbol(", ")); - Local cons2 = String::Concat(cons1, message); - - Local e = Exception::Error(cons2); - - Local obj = e->ToObject(); - obj->Set(String::NewSymbol("errno"), Integer::New(status)); - obj->Set(String::NewSymbol("code"), code); - - TryCatch try_catch; - - cb->Call(v8::Context::GetCurrent()->Global(), 1, &e); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } -} - - -static void HostByNameCb(void *data, - int status, - int timeouts, - struct hostent *hostent) { - HandleScope scope; - - Persistent *cb = cb_unwrap(data); - - if (status != ARES_SUCCESS) { - ResolveError(*cb, status); - cb_destroy(cb); - return; - } - - TryCatch try_catch; - - Local addresses = HostEntToAddresses(hostent); - - Local argv[2] = { Local::New(Null()), addresses}; - - (*cb)->Call(v8::Context::GetCurrent()->Global(), 2, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - cb_destroy(cb); -} - - -static void HostByAddrCb(void *data, - int status, - int timeouts, - struct hostent *hostent) { - HandleScope scope; - - Persistent *cb = cb_unwrap(data); - - if (status != ARES_SUCCESS) { - ResolveError(*cb, status); - cb_destroy(cb); - return; - } - - TryCatch try_catch; - - Local names = HostEntToNames(hostent); - - Local argv[2] = { Local::New(Null()), names }; - - (*cb)->Call(v8::Context::GetCurrent()->Global(), 2, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - cb_destroy(cb); -} - - -static void cb_call(Persistent &cb, int argc, Local *argv) { - TryCatch try_catch; - - cb->Call(v8::Context::GetCurrent()->Global(), argc, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } -} - - -static void ParseAnswerA(QueryArg *arg, unsigned char* abuf, int alen) { - HandleScope scope; - - hostent* host; - - int status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL); - if (status != ARES_SUCCESS) { - ResolveError(arg->js_cb, status); - return; - } - - Local addresses = HostEntToAddresses(host); - ares_free_hostent(host); - - Local argv[2] = { Local::New(Null()), addresses }; - cb_call(arg->js_cb, 2, argv); -} - - -static void ParseAnswerAAAA(QueryArg *arg, unsigned char* abuf, int alen) { - HandleScope scope; - - hostent* host; - - int status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); - if (status != ARES_SUCCESS) { - ResolveError(arg->js_cb, status); - return; - } - - Local addresses = HostEntToAddresses(host); - ares_free_hostent(host); - - Local argv[2] = { Local::New(Null()), addresses}; - cb_call(arg->js_cb, 2, argv); -} - - -static void ParseAnswerCNAME(QueryArg *arg, unsigned char* abuf, int alen) { - HandleScope scope; - - hostent* host; - - int status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL); - if (status != ARES_SUCCESS) { - ResolveError(arg->js_cb, status); - return; - } - - // a CNAME lookup always returns a single record but - // it's probably best to follow the common API here - Local addresses = Array::New(1); - addresses->Set(0, String::New(host->h_name)); - ares_free_hostent(host); - - Local argv[2] = { Local::New(Null()), addresses }; - cb_call(arg->js_cb, 2, argv); -} - - -static void ParseAnswerMX(QueryArg *arg, unsigned char* abuf, int alen) { - HandleScope scope; - - struct ares_mx_reply *mx_out; - - int status = ares_parse_mx_reply(abuf, alen, &mx_out); - if (status != ARES_SUCCESS) { - ResolveError(arg->js_cb, status); - return; - } - - Local mx_records = Array::New(); - - struct ares_mx_reply *current = mx_out; - for (int i = 0; current; ++i, current = current->next) { - Local mx = Object::New(); - - mx->Set(priority_symbol, Integer::New(current->priority)); - mx->Set(exchange_symbol, String::New(current->host)); - - mx_records->Set(Integer::New(i), mx); - } - ares_free_data(mx_out); - - Local argv[2] = { Local::New(Null()), mx_records }; - cb_call(arg->js_cb, 2, argv); -} - - -static void ParseAnswerNS(QueryArg *arg, unsigned char* abuf, int alen) { - HandleScope scope; - - hostent* host; - - int status = ares_parse_ns_reply(abuf, alen, &host); - if (status != ARES_SUCCESS) { - ResolveError(arg->js_cb, status); - return; - } - - Local names = HostEntToNames(host); - ares_free_hostent(host); - - Local argv[2] = { Local::New(Null()), names }; - cb_call(arg->js_cb, 2, argv); -} - - -static void ParseAnswerSRV(QueryArg *arg, unsigned char* abuf, int alen) { - HandleScope scope; - - struct ares_srv_reply *srv_out; - - int status = ares_parse_srv_reply(abuf, alen, &srv_out); - if (status != ARES_SUCCESS) { - ResolveError(arg->js_cb, status); - return; - } - - Local srv_records = Array::New(); - - struct ares_srv_reply *current = srv_out; - for (int i = 0; current; ++i, current = current->next) { - Local srv = Object::New(); - - srv->Set(priority_symbol, Integer::New(current->priority)); - srv->Set(weight_symbol, Integer::New(current->weight)); - srv->Set(port_symbol, Integer::New(current->port)); - srv->Set(name_symbol, String::New(current->host)); - - srv_records->Set(Integer::New(i), srv); - } - ares_free_data(srv_out); - - Local argv[2] = { Local::New(Null()), srv_records }; - cb_call(arg->js_cb, 2, argv); -} - - -static void ParseAnswerTXT(QueryArg *arg, unsigned char* abuf, int alen) { - HandleScope scope; - - struct ares_txt_reply *txt_out; - - int status = ares_parse_txt_reply(abuf, alen, &txt_out); - if (status != ARES_SUCCESS) { - ResolveError(arg->js_cb, status); - return; - } - - Local txt_records = Array::New(); - - struct ares_txt_reply *current = txt_out; - for (int i = 0; current; ++i, current = current->next) { - Local txt = String::New(reinterpret_cast(current->txt)); - txt_records->Set(Integer::New(i), txt); - } - ares_free_data(txt_out); - - - Local argv[2] = { Local::New(Null()), txt_records }; - cb_call(arg->js_cb, 2, argv); -} - - -void Channel::QueryCb(void *arg, - int status, - int timeouts, - unsigned char* abuf, - int alen) { - QueryArg *query_arg = static_cast(arg); - - HandleScope scope; - - if (status != ARES_SUCCESS) { - ResolveError(query_arg->js_cb, status); - delete query_arg; - return; - } - - query_arg->parse_cb(query_arg, abuf, alen); - - delete query_arg; -} - - -void Channel::Initialize(Handle target) { - HandleScope scope; - - Local t = FunctionTemplate::New(Channel::New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("Channel")); - - NODE_SET_PROTOTYPE_METHOD(constructor_template, "getHostByName", Channel::GetHostByName); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "getHostByAddr", Channel::GetHostByAddr); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "query", Channel::Query); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "timeout", Channel::Timeout); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "processFD", Channel::ProcessFD); - - target->Set(String::NewSymbol("Channel"), constructor_template->GetFunction()); - - callback_symbol = NODE_PSYMBOL("callback"); -} - - -Handle Channel::New(const Arguments& args) { - if (!args.IsConstructCall()) { - return FromConstructorTemplate(constructor_template, args); - } - - HandleScope scope; - - struct ares_options options; - int optmask = 0; - - Channel *c = new Channel(); - c->Wrap(args.This()); - - if (args.Length() > 0) { - if(!args[0]->IsObject()) { - return ThrowException(Exception::TypeError( - String::New("Bad Options Argument"))); - } - - Local options_o = Local::Cast(args[0]); - - Local cb = options_o->Get(String::NewSymbol("SOCK_STATE_CB")); - if (!cb.IsEmpty()) { - c->handle_->Set(callback_symbol, cb); - options.sock_state_cb_data = c; - options.sock_state_cb = Channel::SockStateCb; - optmask |= ARES_OPT_SOCK_STATE_CB; - } - } - - ares_init_options(&c->channel, &options, optmask); - - return args.This(); -} - - -Handle Channel::Query(const Arguments& args) { - HandleScope scope; - Channel *c = ObjectWrap::Unwrap(args.Holder()); - assert(c); - - if (!args[0]->IsString()) { - return ThrowException(Exception::TypeError( - String::New("First argument must be a name"))); - } - - if (!args[1]->IsInt32()) { - return ThrowException(Exception::TypeError( - String::New("Second argument must be a query type"))); - } - - if (!args[2]->IsFunction()) { - return ThrowException(Exception::TypeError( - String::New("Third argument must be a callback"))); - } - - String::Utf8Value name(args[0]->ToString()); - int type = args[1]->Int32Value(); - QueryArg::ParseAnswerCb parse_cb; - - switch(type) { - case ns_t_a: - parse_cb = ParseAnswerA; - break; - - case ns_t_aaaa: - parse_cb = ParseAnswerAAAA; - break; - - case ns_t_mx: - parse_cb = ParseAnswerMX; - break; - - case ns_t_ns: - parse_cb = ParseAnswerNS; - break; - - case ns_t_txt: - parse_cb = ParseAnswerTXT; - break; - - case ns_t_srv: - parse_cb = ParseAnswerSRV; - break; - - case ns_t_cname: - parse_cb = ParseAnswerCNAME; - break; - - case ns_t_ptr: - - int length, family; - char address_b[sizeof(struct in6_addr)]; - - if (inet_pton(AF_INET, *name, &address_b) == 1) { - length = sizeof(struct in_addr); - family = AF_INET; - } else if (inet_pton(AF_INET6, *name, &address_b) == 1) { - length = sizeof(struct in6_addr); - family = AF_INET6; - } else { - return ThrowException(Exception::Error(String::New("Invalid IP address"))); - } - - ares_gethostbyaddr(c->channel, address_b, length, family, HostByAddrCb, cb_persist(args[2])); - - return Undefined(); - - default: - return ThrowException(Exception::Error( - String::New("Unsupported query type"))); - } - - QueryArg *query_arg = new QueryArg(args[2], parse_cb); - - ares_query(c->channel, *name, ns_c_in, type, QueryCb, query_arg); - - return Undefined(); -} - - -Handle Channel::GetHostByAddr(const Arguments& args) { - HandleScope scope; - Channel *c = ObjectWrap::Unwrap(args.Holder()); - assert(c); - - if (!args[0]->IsString()) { - return ThrowException(Exception::Error( - String::New("First argument must be a address"))); - } - - if (!args[1]->IsInt32()) { - return ThrowException(Exception::Error( - String::New("Second argument must be an address family"))); - } - - if (!args[2]->IsFunction()) { - return ThrowException(Exception::Error( - String::New("Third argument must be a callback"))); - } - - int family = args[1]->Int32Value(); - if (family != AF_INET6 && family != AF_INET) { - return ThrowException(Exception::Error( - String::New("Unsupported address family"))); - } - - String::Utf8Value address_s(args[0]->ToString()); - - char address_b[sizeof(struct in6_addr)]; - int r = inet_pton(family, *address_s, address_b); - if (r != 1) { - return ThrowException(Exception::Error( - String::New("Invalid network address"))); - } - - int length; - if (family == AF_INET6) - length = sizeof(struct in6_addr); - else - length = sizeof(struct in_addr); - - ares_gethostbyaddr(c->channel, address_b, length, family, HostByAddrCb, cb_persist(args[2])); - - return Undefined(); -} - - - -Handle Channel::GetHostByName(const Arguments& args) { - HandleScope scope; - Channel *c = ObjectWrap::Unwrap(args.Holder()); - assert(c); - - if (!args[0]->IsString()) { - return ThrowException(Exception::Error( - String::New("First argument must be a name"))); - } - - if (!args[1]->IsInt32()) { - return ThrowException(Exception::Error( - String::New("Second argument must be a family"))); - } - - if (!args[2]->IsFunction()) { - return ThrowException(Exception::Error( - String::New("Third argument must be a callback"))); - } - - int family = args[1]->Int32Value(); - if (family != AF_INET6 && family != AF_INET) { - return ThrowException(Exception::Error( - String::New("Unsupported address family"))); - } - - String::Utf8Value name(args[0]->ToString()); - - ares_gethostbyname(c->channel, *name, family, HostByNameCb, cb_persist(args[2])); - - return Undefined(); -} - - -Handle Channel::Timeout(const Arguments& args) { - HandleScope scope; - Channel *c = ObjectWrap::Unwrap(args.Holder()); - assert(c); - - if (!args[0]->IsInt32()) { - return ThrowException(Exception::Error( - String::New("First argument must be an integer number of milliseconds"))); - } - - struct timeval tvbuf, maxtv, *ret; - - int64_t time = args[0]->IntegerValue(); - maxtv.tv_sec = time/1000; - maxtv.tv_usec = (time % 1000) * 1000; - - ret = ares_timeout(c->channel, &maxtv, &tvbuf); - - return scope.Close(Integer::New(ret->tv_sec * 1000 + ret->tv_usec / 1000)); -} - - -Handle Channel::ProcessFD(const Arguments& args) { - HandleScope scope; - Channel *c = ObjectWrap::Unwrap(args.Holder()); - assert(c); - - int read_fd, write_fd; - - if (!args[0]->IsInt32()) { - return ThrowException(Exception::Error( - String::New("First argument must be a file descriptor or SOCKET_BAD"))); - } - - read_fd = args[0]->Int32Value(); - - if (args.Length() > 1) { - - if (!args[1]->IsInt32()) { - return ThrowException(Exception::Error( - String::New("Second argument must be a file descriptor or SOCKET_BAD"))); - } - write_fd = args[1]->Int32Value(); - - } else { - write_fd = ARES_SOCKET_BAD; - } - - ares_process_fd(c->channel, read_fd, write_fd); - - return Undefined(); -} - - -void Channel::SockStateCb(void *data, ares_socket_t sock, int read, int write) { - Channel *c = static_cast(data); - HandleScope scope; - - Local callback_v = c->handle_->Get(callback_symbol); - if (!callback_v->IsFunction()) return; - Local callback = Local::Cast(callback_v); - - Local argv[3]; - - argv[0] = Integer::New(sock); - argv[1] = Integer::New(read); - argv[2] = Integer::New(write); - - TryCatch try_catch; - - callback->Call(c->handle_, 3, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } -} - - - - -} // namespace node - -NODE_MODULE(node_cares, node::Cares::Initialize); diff --git a/src/node_cares.h b/src/node_cares.h deleted file mode 100644 index 0af763e3090..00000000000 --- a/src/node_cares.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef NODE_CARES_H_ -#define NODE_CARES_H_ - -#include -#include -#include - -namespace node { - -class Cares { - public: - static void Initialize(v8::Handle target); -}; - -} // namespace node -#endif // NODE_CARES_H_ diff --git a/src/node_extensions.h b/src/node_extensions.h index f4ff7a8dc0c..6f146544cd7 100644 --- a/src/node_extensions.h +++ b/src/node_extensions.h @@ -22,9 +22,6 @@ NODE_EXT_LIST_START NODE_EXT_LIST_ITEM(node_buffer) -#ifdef __POSIX__ -NODE_EXT_LIST_ITEM(node_cares) -#endif #if HAVE_OPENSSL NODE_EXT_LIST_ITEM(node_crypto) #endif diff --git a/wscript b/wscript index 2f1b959c990..a352893849e 100644 --- a/wscript +++ b/wscript @@ -902,7 +902,6 @@ def build(bld): if sys.platform.startswith("win32"): node.source += " src/node_stdio_win32.cc " else: - node.source += " src/node_cares.cc " node.source += " src/node_signal_watcher.cc " node.source += " src/node_stat_watcher.cc " node.source += " src/node_io_watcher.cc "