diff --git a/lib/net.js b/lib/net.js index f8b77b2df6e..c8d7f60913c 100644 --- a/lib/net.js +++ b/lib/net.js @@ -24,6 +24,7 @@ var Stream = require('stream'); var timers = require('timers'); var util = require('util'); var assert = require('assert'); +var cares = process.binding('cares_wrap'); var cluster; function noop() {} @@ -1091,27 +1092,7 @@ Server.prototype._setupSlave = function(socketList) { // TODO: isIP should be moved to the DNS code. Putting it here now because // this is what the legacy system did. -// NOTE: This does not accept IPv6 with an IPv4 dotted address at the end, -// and it does not detect more than one double : in a string. -exports.isIP = function(input) { - if (!input) { - return 0; - } else if (/^(\d?\d?\d)\.(\d?\d?\d)\.(\d?\d?\d)\.(\d?\d?\d)$/.test(input)) { - var parts = input.split('.'); - for (var i = 0; i < parts.length; i++) { - var part = parseInt(parts[i]); - if (part < 0 || 255 < part) { - return 0; - } - } - return 4; - } else if (/^::|^::1|^([a-fA-F0-9]{1,4}::?){1,7}([a-fA-F0-9]{1,4})$/.test( - input)) { - return 6; - } else { - return 0; - } -}; +exports.isIP = cares.isIP; exports.isIPv4 = function(input) { diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 30d72387167..049fdb97d77 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -685,6 +685,24 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { } +static Handle IsIP(const Arguments& args) { + HandleScope scope; + + String::AsciiValue ip(args[0]); + char address_buffer[sizeof(struct in6_addr)]; + + if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 1) { + return scope.Close(v8::Integer::New(4)); + } + + if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 1) { + return scope.Close(v8::Integer::New(6)); + } + + return scope.Close(v8::Integer::New(0)); +} + + static Handle GetAddrInfo(const Arguments& args) { HandleScope scope; @@ -750,6 +768,7 @@ static void Initialize(Handle target) { NODE_SET_METHOD(target, "getHostByName", QueryWithFamily); NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo); + NODE_SET_METHOD(target, "isIP", IsIP); target->Set(String::NewSymbol("AF_INET"), Integer::New(AF_INET)); target->Set(String::NewSymbol("AF_INET6"), Integer::New(AF_INET6)); diff --git a/test/simple/test-net-isip.js b/test/simple/test-net-isip.js index 4f60f502135..0d324007f22 100644 --- a/test/simple/test-net-isip.js +++ b/test/simple/test-net-isip.js @@ -31,7 +31,20 @@ assert.equal(net.isIP('0000:0000:0000:0000:0000:0000:0000:0000::0000'), 0); assert.equal(net.isIP('1050:0:0:0:5:600:300c:326b'), 6); assert.equal(net.isIP('2001:252:0:1::2008:6'), 6); assert.equal(net.isIP('2001:dead:beef:1::2008:6'), 6); +assert.equal(net.isIP('2001::'), 6); +assert.equal(net.isIP('2001:dead::'), 6); +assert.equal(net.isIP('2001:dead:beef::'), 6); +assert.equal(net.isIP('2001:dead:beef:1::'), 6); assert.equal(net.isIP('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 6); +assert.equal(net.isIP(':2001:252:0:1::2008:6:'), 0); +assert.equal(net.isIP(':2001:252:0:1::2008:6'), 0); +assert.equal(net.isIP('2001:252:0:1::2008:6:'), 0); +assert.equal(net.isIP('2001:252::1::2008:6'), 0); +assert.equal(net.isIP('::2001:252:1:2008:6'), 6); +assert.equal(net.isIP('::2001:252:1:1.1.1.1'), 6); +assert.equal(net.isIP('::2001:252:1:255.255.255.255'), 6); +assert.equal(net.isIP('::2001:252:1:255.255.255.255.76'), 0); +assert.equal(net.isIP('::anything'), 0); assert.equal(net.isIP('::1'), 6); assert.equal(net.isIP('::'), 6); assert.equal(net.isIP('0000:0000:0000:0000:0000:0000:12345:0000'), 0); @@ -45,4 +58,4 @@ assert.equal(net.isIPv4('2001:252:0:1::2008:6'), false); assert.equal(net.isIPv6('127.0.0.1'), false); assert.equal(net.isIPv6('example.com'), false); -assert.equal(net.isIPv6('2001:252:0:1::2008:6'), true); \ No newline at end of file +assert.equal(net.isIPv6('2001:252:0:1::2008:6'), true);