Skip to content

Commit 72c64f2

Browse files
committed
dgram: skip the custom lookup for literal IP addresses
A user-supplied lookup function is no longer called when the destination is a literal IP of the socket's family; the address is used directly, matching net.connect(), which skips the lookup for a literal IP host before consulting options.lookup. This is a breaking change for a lookup that expected to be invoked for IP addresses. Refs: DataDog/dd-trace-js#2984 Signed-off-by: Ruben Bridgewater <ruben@bridgewater.de>
1 parent 6486166 commit 72c64f2

3 files changed

Lines changed: 36 additions & 21 deletions

File tree

doc/api/dgram.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,8 +1039,8 @@ changes:
10391039
* `recvBufferSize` {number} Sets the `SO_RCVBUF` socket value.
10401040
* `sendBufferSize` {number} Sets the `SO_SNDBUF` socket value.
10411041
* `lookup` {Function} Custom lookup function. **Default:** [`dns.lookup()`][].
1042-
When the default is used, a literal IP address of the socket's family
1043-
resolves to itself without calling [`dns.lookup()`][].
1042+
A literal IP address of the socket's family resolves to itself; the lookup
1043+
function is not called for it.
10441044
* `signal` {AbortSignal} An AbortSignal that may be used to close a socket.
10451045
* `receiveBlockList` {net.BlockList} `receiveBlockList` can be used for discarding
10461046
inbound datagram to specific IP addresses, IP ranges, or IP subnets. This does not

lib/internal/dgram.js

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,32 +19,35 @@ const { UV_EINVAL } = internalBinding('uv');
1919
const kStateSymbol = Symbol('state symbol');
2020
let dns; // Lazy load for startup performance.
2121

22+
function lookupOrSkip(lookup, address, family, callback) {
23+
if (isIP(address) === family) {
24+
process.nextTick(callback, null, address, family);
25+
return;
26+
}
27+
return lookup(address, family, callback);
28+
}
2229

2330
function lookup4(lookup, address, callback) {
24-
return lookup(address || '127.0.0.1', 4, callback);
31+
if (address) {
32+
return lookupOrSkip(lookup, address, 4, callback);
33+
}
34+
process.nextTick(callback, null, '127.0.0.1', 4);
2535
}
2636

27-
2837
function lookup6(lookup, address, callback) {
29-
return lookup(address || '::1', 6, callback);
30-
}
31-
32-
// A literal IP of the socket's family resolves to itself, so skip dns.lookup().
33-
// Defer with nextTick to keep the callback async (e.g. bind()'s 'listening').
34-
function defaultLookup(address, family, callback) {
35-
if (isIP(address) === family) {
36-
process.nextTick(callback, null, address, family);
37-
return;
38+
if (address) {
39+
return lookupOrSkip(lookup, address, 6, callback);
3840
}
39-
if (dns === undefined) {
40-
dns = require('dns');
41-
}
42-
return dns.lookup(address, family, callback);
41+
process.nextTick(callback, null, '::1', 6);
4342
}
4443

4544
function newHandle(type, lookup) {
4645
if (lookup === undefined) {
47-
lookup = defaultLookup;
46+
if (dns === undefined) {
47+
dns = require('dns');
48+
}
49+
50+
lookup = dns.lookup;
4851
} else {
4952
validateFunction(lookup, 'lookup');
5053
}

test/parallel/test-dgram-custom-lookup.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,30 @@ const originalLookup = dns.lookup;
99
{
1010
// Verify that the provided lookup function is called.
1111
const lookup = common.mustCall((host, family, callback) => {
12-
originalLookup(host, family, callback);
12+
assert.strictEqual(host, 'example.invalid');
13+
callback(null, '127.0.0.1', 4);
1314
});
1415

1516
const socket = dgram.createSocket({ type: 'udp4', lookup });
1617

17-
socket.bind(common.mustCall(() => {
18+
socket.bind(0, 'example.invalid', common.mustCall(() => {
19+
socket.close();
20+
}));
21+
}
22+
23+
{
24+
// IPs resolve to themselves, so a custom lookup is not called.
25+
const lookup = common.mustNotCall('lookup ran for a literal IP address');
26+
27+
const socket = dgram.createSocket({ type: 'udp4', lookup });
28+
29+
socket.bind(0, '127.0.0.1', common.mustCall(() => {
1830
socket.close();
1931
}));
2032
}
2133

2234
{
23-
// Verify that the default lookup forwards host names to dns.lookup().
35+
// Verify that lookup defaults to dns.lookup().
2436
dns.lookup = common.mustCall((host, family, callback) => {
2537
dns.lookup = originalLookup;
2638
assert.strictEqual(host, 'example.invalid');

0 commit comments

Comments
 (0)