Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib,src: port isIPv4() to js #18398

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 1 addition & 26 deletions lib/dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
const util = require('util');

const cares = process.binding('cares_wrap');
const { isLegalPort } = require('internal/net');
const { isIP, isIPv4, isLegalPort } = require('internal/net');
const { customPromisifyArgs } = require('internal/util');
const errors = require('internal/errors');
const {
Expand All @@ -38,7 +38,6 @@ const {
GetNameInfoReqWrap,
QueryReqWrap,
ChannelWrap,
isIP
} = cares;

function errnoException(err, syscall, hostname) {
Expand Down Expand Up @@ -66,30 +65,6 @@ function errnoException(err, syscall, hostname) {
}

const IANA_DNS_PORT = 53;
const digits = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48-63
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 64-79
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-95
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96-111
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 112-127
];
function isIPv4(str) {
if (!digits[str.charCodeAt(0)]) return false;
if (str.length === 1) return false;
if (str.charCodeAt(1) === 46/*'.'*/)
return true;
else if (!digits[str.charCodeAt(1)])
return false;
if (str.length === 2) return false;
if (str.charCodeAt(2) === 46/*'.'*/)
return true;
else if (!digits[str.charCodeAt(2)])
return false;
return (str.length > 3 && str.charCodeAt(3) === 46/*'.'*/);
}


function onlookup(err, addresses) {
Expand Down
17 changes: 17 additions & 0 deletions lib/internal/net.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
'use strict';

const Buffer = require('buffer').Buffer;
const { isIPv6 } = process.binding('cares_wrap');
const { writeBuffer } = process.binding('fs');

const octet = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
const re = new RegExp(`^${octet}[.]${octet}[.]${octet}[.]${octet}$`);

function isIPv4(s) {
return re.test(s);
}

function isIP(s) {
if (isIPv4(s)) return 4;
if (isIPv6(s)) return 6;
return 0;
}

// Check that the port number is not NaN when coerced to a number,
// is an integer and that it falls within the legal range of port numbers.
function isLegalPort(port) {
Expand Down Expand Up @@ -33,6 +47,9 @@ function makeSyncWrite(fd) {
}

module.exports = {
isIP,
isIPv4,
isIPv6,
isLegalPort,
makeSyncWrite,
normalizedArgsSymbol: Symbol('normalizedArgs')
Expand Down
14 changes: 8 additions & 6 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ const timers = require('timers');
const util = require('util');
const internalUtil = require('internal/util');
const {
isIP,
isIPv4,
isIPv6,
isLegalPort,
normalizedArgsSymbol,
makeSyncWrite
} = require('internal/net');
const assert = require('assert');
const cares = process.binding('cares_wrap');
const {
UV_EADDRINUSE,
UV_EINVAL,
Expand Down Expand Up @@ -1066,7 +1068,7 @@ function lookupAndConnect(self, options) {
var localAddress = options.localAddress;
var localPort = options.localPort;

if (localAddress && !cares.isIP(localAddress)) {
if (localAddress && !isIP(localAddress)) {
throw new errors.TypeError('ERR_INVALID_IP_ADDRESS', localAddress);
}

Expand All @@ -1091,7 +1093,7 @@ function lookupAndConnect(self, options) {
port |= 0;

// If host is an IP, skip performing a lookup
var addressType = cares.isIP(host);
var addressType = isIP(host);
if (addressType) {
nextTick(self[async_id_symbol], function() {
if (self.connecting)
Expand Down Expand Up @@ -1775,9 +1777,9 @@ module.exports = {
connect,
createConnection: connect,
createServer,
isIP: cares.isIP,
isIPv4: cares.isIPv4,
isIPv6: cares.isIPv6,
isIP: isIP,
isIPv4: isIPv4,
isIPv6: isIPv6,
Server,
Socket,
Stream: Socket, // Legacy naming
Expand Down
60 changes: 15 additions & 45 deletions src/cares_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1876,60 +1876,32 @@ void AfterGetNameInfo(uv_getnameinfo_t* req,
delete req_wrap;
}


void IsIP(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value ip(args.GetIsolate(), args[0]);
char address_buffer[sizeof(struct in6_addr)];

int rc = 0;
if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0)
rc = 4;
else if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0)
rc = 6;

args.GetReturnValue().Set(rc);
}

void IsIPv4(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value ip(args.GetIsolate(), args[0]);
char address_buffer[sizeof(struct in_addr)];

if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0) {
args.GetReturnValue().Set(true);
} else {
args.GetReturnValue().Set(false);
}
using ParseIPResult = decltype(static_cast<ares_addr_port_node*>(0)->addr);

int ParseIP(const char* ip, ParseIPResult* result = nullptr) {
ParseIPResult tmp;
if (result == nullptr) result = &tmp;
if (0 == uv_inet_pton(AF_INET, ip, result)) return 4;
if (0 == uv_inet_pton(AF_INET6, ip, result)) return 6;
return 0;
}

void IsIPv6(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value ip(args.GetIsolate(), args[0]);
char address_buffer[sizeof(struct in6_addr)];

if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0) {
args.GetReturnValue().Set(true);
} else {
args.GetReturnValue().Set(false);
}
args.GetReturnValue().Set(6 == ParseIP(*ip));
}

void CanonicalizeIP(const FunctionCallbackInfo<Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
node::Utf8Value ip(isolate, args[0]);
char address_buffer[sizeof(struct in6_addr)];
char canonical_ip[INET6_ADDRSTRLEN];

int af;
if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0)
af = AF_INET;
else if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0)
af = AF_INET6;
else
return;

int err = uv_inet_ntop(af, address_buffer, canonical_ip,
sizeof(canonical_ip));
CHECK_EQ(err, 0);
ParseIPResult result;
const int rc = ParseIP(*ip, &result);
if (rc == 0) return;

char canonical_ip[INET6_ADDRSTRLEN];
const int af = (rc == 4 ? AF_INET : AF_INET6);
CHECK_EQ(0, uv_inet_ntop(af, &result, canonical_ip, sizeof(canonical_ip)));
args.GetReturnValue().Set(String::NewFromUtf8(isolate, canonical_ip));
}

Expand Down Expand Up @@ -2156,8 +2128,6 @@ void Initialize(Local<Object> target,

env->SetMethod(target, "getaddrinfo", GetAddrInfo);
env->SetMethod(target, "getnameinfo", GetNameInfo);
env->SetMethod(target, "isIP", IsIP);
env->SetMethod(target, "isIPv4", IsIPv4);
env->SetMethod(target, "isIPv6", IsIPv6);
env->SetMethod(target, "canonicalizeIP", CanonicalizeIP);

Expand Down