diff --git a/lib/net.js b/lib/net.js index 46d7d0b173a..aeb37b2c34f 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() {} @@ -1119,27 +1120,7 @@ Server.prototype.unref = function() { // 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]{0,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 2e509abaded..4d01ee40261 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -813,6 +813,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).code == UV_OK) { + return scope.Close(v8::Integer::New(4)); + } + + if (uv_inet_pton(AF_INET6, *ip, &address_buffer).code == UV_OK) { + return scope.Close(v8::Integer::New(6)); + } + + return scope.Close(v8::Integer::New(0)); +} + + static Handle GetAddrInfo(const Arguments& args) { HandleScope scope; @@ -886,6 +904,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 353cad6747f..0d324007f22 100644 --- a/test/simple/test-net-isip.js +++ b/test/simple/test-net-isip.js @@ -36,6 +36,15 @@ 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); @@ -49,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);