net: make server.address() return an integer for family

`dns.lookup` options only accepts integer for `family` options,
having a string doesn't really make sense here.

PR-URL: https://github.com/nodejs/node/pull/41431
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
Antoine du Hamel 2022-01-07 17:24:40 +01:00
parent 6706be1cdb
commit 3a26db9697
21 changed files with 40 additions and 33 deletions

View File

@ -760,7 +760,7 @@ protoGetter('remoteAddress', function remoteAddress() {
}); });
protoGetter('remoteFamily', function remoteFamily() { protoGetter('remoteFamily', function remoteFamily() {
return this._getpeername().family; return `IPv${this._getpeername().family}`;
}); });
protoGetter('remotePort', function remotePort() { protoGetter('remotePort', function remotePort() {

View File

@ -216,7 +216,7 @@ function getCIDR(address, netmask, family) {
let groupLength = 8; let groupLength = 8;
let hasZeros = false; let hasZeros = false;
if (family === 'IPv6') { if (family === 6) {
split = ':'; split = ':';
range = 16; range = 16;
groupLength = 16; groupLength = 16;
@ -248,7 +248,7 @@ function getCIDR(address, netmask, family) {
* @returns {Record<string, Array<{ * @returns {Record<string, Array<{
* address: string * address: string
* netmask: string * netmask: string
* family: 'IPv4' | 'IPv6' * family: 4 | 6
* mac: string * mac: string
* internal: boolean * internal: boolean
* scopeid: number * scopeid: number

View File

@ -289,8 +289,6 @@ constexpr size_t kFsStatsBufferLength =
V(input_string, "input") \ V(input_string, "input") \
V(internal_binding_string, "internalBinding") \ V(internal_binding_string, "internalBinding") \
V(internal_string, "internal") \ V(internal_string, "internal") \
V(ipv4_string, "IPv4") \
V(ipv6_string, "IPv6") \
V(isclosing_string, "isClosing") \ V(isclosing_string, "isClosing") \
V(issuer_string, "issuer") \ V(issuer_string, "issuer") \
V(issuercert_string, "issuerCertificate") \ V(issuercert_string, "issuerCertificate") \

View File

@ -174,7 +174,8 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
char ip[INET6_ADDRSTRLEN]; char ip[INET6_ADDRSTRLEN];
char netmask[INET6_ADDRSTRLEN]; char netmask[INET6_ADDRSTRLEN];
std::array<char, 18> mac; std::array<char, 18> mac;
Local<String> name, family; Local<String> name;
Local<Integer> family;
int err = uv_interface_addresses(&interfaces, &count); int err = uv_interface_addresses(&interfaces, &count);
@ -214,14 +215,14 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
if (interfaces[i].address.address4.sin_family == AF_INET) { if (interfaces[i].address.address4.sin_family == AF_INET) {
uv_ip4_name(&interfaces[i].address.address4, ip, sizeof(ip)); uv_ip4_name(&interfaces[i].address.address4, ip, sizeof(ip));
uv_ip4_name(&interfaces[i].netmask.netmask4, netmask, sizeof(netmask)); uv_ip4_name(&interfaces[i].netmask.netmask4, netmask, sizeof(netmask));
family = env->ipv4_string(); family = Integer::New(env->isolate(), 4);
} else if (interfaces[i].address.address4.sin_family == AF_INET6) { } else if (interfaces[i].address.address4.sin_family == AF_INET6) {
uv_ip6_name(&interfaces[i].address.address6, ip, sizeof(ip)); uv_ip6_name(&interfaces[i].address.address6, ip, sizeof(ip));
uv_ip6_name(&interfaces[i].netmask.netmask6, netmask, sizeof(netmask)); uv_ip6_name(&interfaces[i].netmask.netmask6, netmask, sizeof(netmask));
family = env->ipv6_string(); family = Integer::New(env->isolate(), 6);
} else { } else {
strncpy(ip, "<unknown sa family>", INET6_ADDRSTRLEN); strncpy(ip, "<unknown sa family>", INET6_ADDRSTRLEN);
family = env->unknown_string(); family = Integer::New(env->isolate(), 0);
} }
result.emplace_back(name); result.emplace_back(name);

View File

@ -380,7 +380,7 @@ MaybeLocal<Object> AddressToJS(Environment* env,
OneByteString(env->isolate(), ip)).Check(); OneByteString(env->isolate(), ip)).Check();
info->Set(env->context(), info->Set(env->context(),
env->family_string(), env->family_string(),
env->ipv6_string()).Check(); Integer::New(env->isolate(), 6)).Check();
info->Set(env->context(), info->Set(env->context(),
env->port_string(), env->port_string(),
Integer::New(env->isolate(), port)).Check(); Integer::New(env->isolate(), port)).Check();
@ -395,7 +395,7 @@ MaybeLocal<Object> AddressToJS(Environment* env,
OneByteString(env->isolate(), ip)).Check(); OneByteString(env->isolate(), ip)).Check();
info->Set(env->context(), info->Set(env->context(),
env->family_string(), env->family_string(),
env->ipv4_string()).Check(); Integer::New(env->isolate(), 4)).Check();
info->Set(env->context(), info->Set(env->context(),
env->port_string(), env->port_string(),
Integer::New(env->isolate(), port)).Check(); Integer::New(env->isolate(), port)).Check();

View File

@ -845,7 +845,7 @@ const common = {
const re = isWindows ? /Loopback Pseudo-Interface/ : /lo/; const re = isWindows ? /Loopback Pseudo-Interface/ : /lo/;
return Object.keys(iFaces).some((name) => { return Object.keys(iFaces).some((name) => {
return re.test(name) && return re.test(name) &&
iFaces[name].some(({ family }) => family === 'IPv6'); iFaces[name].some(({ family }) => family === 6);
}); });
}, },

View File

@ -16,7 +16,7 @@ class FakeUDPWrap extends EventEmitter {
this._handle.onwrite = this._handle.onwrite =
(wrap, buffers, addr) => this._write(wrap, buffers, addr); (wrap, buffers, addr) => this._write(wrap, buffers, addr);
this._handle.getsockname = (obj) => { this._handle.getsockname = (obj) => {
Object.assign(obj, { address: '127.0.0.1', family: 'IPv4', port: 1337 }); Object.assign(obj, { address: '127.0.0.1', family: 4, port: 1337 });
return 0; return 0;
}; };
@ -72,8 +72,8 @@ class FakeUDPWrap extends EventEmitter {
let familyInt; let familyInt;
switch (family) { switch (family) {
case 'IPv4': familyInt = 4; break; case 4: familyInt = 4; break;
case 'IPv6': familyInt = 6; break; case 6: familyInt = 6; break;
default: throw new Error('bad family'); default: throw new Error('bad family');
} }

View File

@ -39,10 +39,10 @@ const internalInterfaces = Object.values(os.networkInterfaces()).flat().filter(
); );
for (const iface of internalInterfaces) { for (const iface of internalInterfaces) {
testListeningOptions.push({ testListeningOptions.push({
hostname: iface?.family === 'IPv6' ? `[${iface?.address}]` : iface?.address, hostname: iface?.family === 6 ? `[${iface.address}]` : iface?.address,
listenOptions: { listenOptions: {
host: iface?.address, host: iface?.address,
ipv6Only: iface?.family === 'IPv6' ipv6Only: iface?.family === 6
} }
}); });
} }

View File

@ -47,7 +47,7 @@ get_bindAddress: for (const name in networkInterfaces) {
const interfaces = networkInterfaces[name]; const interfaces = networkInterfaces[name];
for (let i = 0; i < interfaces.length; i++) { for (let i = 0; i < interfaces.length; i++) {
const localInterface = interfaces[i]; const localInterface = interfaces[i];
if (!localInterface.internal && localInterface.family === 'IPv4') { if (!localInterface.internal && localInterface.family === 4) {
bindAddress = localInterface.address; bindAddress = localInterface.address;
break get_bindAddress; break get_bindAddress;
} }

View File

@ -49,7 +49,7 @@ const TMPL = (tail) => `${NOW} - ${tail}`;
const interfaceAddress = ((networkInterfaces) => { const interfaceAddress = ((networkInterfaces) => {
for (const name in networkInterfaces) { for (const name in networkInterfaces) {
for (const localInterface of networkInterfaces[name]) { for (const localInterface of networkInterfaces[name]) {
if (!localInterface.internal && localInterface.family === FAM) { if (!localInterface.internal && `IPv${localInterface.family}` === FAM) {
let interfaceAddress = localInterface.address; let interfaceAddress = localInterface.address;
// On Windows, IPv6 would need: `%${localInterface.scopeid}` // On Windows, IPv6 would need: `%${localInterface.scopeid}`
if (FAM === 'IPv6') if (FAM === 'IPv6')

View File

@ -28,7 +28,7 @@ get_sourceAddress: for (const name in networkInterfaces) {
const interfaces = networkInterfaces[name]; const interfaces = networkInterfaces[name];
for (let i = 0; i < interfaces.length; i++) { for (let i = 0; i < interfaces.length; i++) {
const localInterface = interfaces[i]; const localInterface = interfaces[i];
if (!localInterface.internal && localInterface.family === 'IPv4') { if (!localInterface.internal && localInterface.family === 4) {
sourceAddress = localInterface.address; sourceAddress = localInterface.address;
break get_sourceAddress; break get_sourceAddress;
} }

View File

@ -28,7 +28,7 @@ get_sourceAddress: for (const name in networkInterfaces) {
const interfaces = networkInterfaces[name]; const interfaces = networkInterfaces[name];
for (let i = 0; i < interfaces.length; i++) { for (let i = 0; i < interfaces.length; i++) {
const localInterface = interfaces[i]; const localInterface = interfaces[i];
if (!localInterface.internal && localInterface.family === 'IPv6') { if (!localInterface.internal && localInterface.family === 6) {
sourceAddress = localInterface.address; sourceAddress = localInterface.address;
break get_sourceAddress; break get_sourceAddress;
} }

View File

@ -1,3 +1,5 @@
// Flags: --dns-result-order=ipv4first
'use strict'; 'use strict';
const common = require('../common'); const common = require('../common');
const { addresses } = require('../common/internet'); const { addresses } = require('../common/internet');

View File

@ -35,7 +35,7 @@ const dgram = require('dgram');
assert.strictEqual(typeof address.port, 'number'); assert.strictEqual(typeof address.port, 'number');
assert.ok(isFinite(address.port)); assert.ok(isFinite(address.port));
assert.ok(address.port > 0); assert.ok(address.port > 0);
assert.strictEqual(address.family, 'IPv4'); assert.strictEqual(address.family, 4);
socket.close(); socket.close();
})); }));
@ -59,7 +59,7 @@ if (common.hasIPv6) {
assert.strictEqual(typeof address.port, 'number'); assert.strictEqual(typeof address.port, 'number');
assert.ok(isFinite(address.port)); assert.ok(isFinite(address.port));
assert.ok(address.port > 0); assert.ok(address.port > 0);
assert.strictEqual(address.family, 'IPv6'); assert.strictEqual(address.family, 6);
socket.close(); socket.close();
})); }));

View File

@ -12,7 +12,7 @@ const invalidPort = -1 >>> 0;
net.Server().listen(0, function() { net.Server().listen(0, function() {
const address = this.address(); const address = this.address();
const key = `${address.family.slice(-1)}:${address.address}:0`; const key = `${address.family}:${address.address}:0`;
assert.strictEqual(this._connectionKey, key); assert.strictEqual(this._connectionKey, key);
this.close(); this.close();

View File

@ -16,5 +16,11 @@ const server = net.createServer(common.mustCall(function(conn) {
client.end(); client.end();
})); }));
client.connect(server.address()); const address = server.address();
if (!common.hasIPv6 && address.family === 6) {
// Necessary to pass CI running inside containers.
client.connect(address.port);
} else {
client.connect(address);
}
})); }));

View File

@ -9,7 +9,7 @@ const net = require('net');
const server = net.createServer(common.mustCall(function(conn) { const server = net.createServer(common.mustCall(function(conn) {
conn.end(); conn.end();
server.close(); server.close();
})).listen(0, common.mustCall(function() { })).listen(0, 'localhost', common.mustCall(function() {
const client = new net.Socket(); const client = new net.Socket();
client.on('ready', common.mustCall(function() { client.on('ready', common.mustCall(function() {

View File

@ -138,7 +138,7 @@ switch (platform) {
const expected = [{ const expected = [{
address: '127.0.0.1', address: '127.0.0.1',
netmask: '255.0.0.0', netmask: '255.0.0.0',
family: 'IPv4', family: 4,
mac: '00:00:00:00:00:00', mac: '00:00:00:00:00:00',
internal: true, internal: true,
cidr: '127.0.0.1/8' cidr: '127.0.0.1/8'
@ -154,7 +154,7 @@ switch (platform) {
const expected = [{ const expected = [{
address: '127.0.0.1', address: '127.0.0.1',
netmask: '255.0.0.0', netmask: '255.0.0.0',
family: 'IPv4', family: 4,
mac: '00:00:00:00:00:00', mac: '00:00:00:00:00:00',
internal: true, internal: true,
cidr: '127.0.0.1/8' cidr: '127.0.0.1/8'

View File

@ -18,9 +18,9 @@ const r = (common.hasIPv6 ?
server.bind6('::', 0) : server.bind6('::', 0) :
server.bind('0.0.0.0', 0)); server.bind('0.0.0.0', 0));
assert.strictEqual(r, 0); assert.strictEqual(r, 0);
let port = {};
const port = {};
server.getsockname(port); server.getsockname(port);
port = port.port;
server.listen(128); server.listen(128);

View File

@ -26,7 +26,7 @@ const net = require('net');
// Test on IPv4 Server // Test on IPv4 Server
{ {
const family = 'IPv4'; const family = 4;
const server = net.createServer(); const server = net.createServer();
server.on('error', common.mustNotCall()); server.on('error', common.mustNotCall());
@ -46,7 +46,7 @@ if (!common.hasIPv6) {
return; return;
} }
const family6 = 'IPv6'; const family6 = 6;
const anycast6 = '::'; const anycast6 = '::';
// Test on IPv6 Server // Test on IPv6 Server

View File

@ -24,7 +24,7 @@ const net = require('net');
const address = server.address(); const address = server.address();
assert.strictEqual(address.port, common.PORT); assert.strictEqual(address.port, common.PORT);
if (address.family === 'IPv6') if (address.family === 6)
assert.strictEqual(server._connectionKey, `6::::${address.port}`); assert.strictEqual(server._connectionKey, `6::::${address.port}`);
else else
assert.strictEqual(server._connectionKey, `4:0.0.0.0:${address.port}`); assert.strictEqual(server._connectionKey, `4:0.0.0.0:${address.port}`);