net: support blocklist in net.connect · nodejs/node@bacfe6d · GitHub
Skip to content

Commit bacfe6d

Browse files
theanarkhruyadorno
authored andcommitted
net: support blocklist in net.connect
PR-URL: #56075 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent c4a97d8 commit bacfe6d

5 files changed

Lines changed: 99 additions & 2 deletions

File tree

doc/api/errors.md

Lines changed: 6 additions & 0 deletions

doc/api/net.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,8 @@ For TCP connections, available `options` are:
10891089
* `noDelay` {boolean} If set to `true`, it disables the use of Nagle's algorithm
10901090
immediately after the socket is established. **Default:** `false`.
10911091
* `port` {number} Required. Port the socket should connect to.
1092+
* `blockList` {net.BlockList} `blockList` can be used for disabling outbound
1093+
access to specific IP addresses, IP ranges, or IP subnets.
10921094

10931095
For [IPC][] connections, available `options` are:
10941096

lib/internal/errors.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,9 @@ E('ERR_IPC_CHANNEL_CLOSED', 'Channel closed', Error);
15551555
E('ERR_IPC_DISCONNECTED', 'IPC channel is already disconnected', Error);
15561556
E('ERR_IPC_ONE_PIPE', 'Child process can have only one IPC pipe', Error);
15571557
E('ERR_IPC_SYNC_FORK', 'IPC cannot be used with synchronous forks', Error);
1558+
E('ERR_IP_BLOCKED', function(ip) {
1559+
return `IP(${ip}) is blocked by net.BlockList`;
1560+
}, Error);
15581561
E(
15591562
'ERR_LOADER_CHAIN_INCOMPLETE',
15601563
'"%s" did not call the next hook in its chain and did not' +

lib/net.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ const {
103103
ERR_INVALID_FD_TYPE,
104104
ERR_INVALID_HANDLE_TYPE,
105105
ERR_INVALID_IP_ADDRESS,
106+
ERR_IP_BLOCKED,
106107
ERR_MISSING_ARGS,
107108
ERR_SERVER_ALREADY_LISTEN,
108109
ERR_SERVER_NOT_RUNNING,
@@ -510,6 +511,12 @@ function Socket(options) {
510511
// Used after `.destroy()`
511512
this[kBytesRead] = 0;
512513
this[kBytesWritten] = 0;
514+
if (options.blockList) {
515+
if (!module.exports.BlockList.isBlockList(options.blockList)) {
516+
throw new ERR_INVALID_ARG_TYPE('options.blockList', 'net.BlockList', options.blockList);
517+
}
518+
this.blockList = options.blockList;
519+
}
513520
}
514521
ObjectSetPrototypeOf(Socket.prototype, stream.Duplex.prototype);
515522
ObjectSetPrototypeOf(Socket, stream.Duplex);
@@ -1073,6 +1080,10 @@ function internalConnect(
10731080
self.emit('connectionAttempt', address, port, addressType);
10741081

10751082
if (addressType === 6 || addressType === 4) {
1083+
if (self.blockList?.check(address, `ipv${addressType}`)) {
1084+
self.destroy(new ERR_IP_BLOCKED(address));
1085+
return;
1086+
}
10761087
const req = new TCPConnectWrap();
10771088
req.oncomplete = afterConnect;
10781089
req.address = address;
@@ -1162,6 +1173,14 @@ function internalConnectMultiple(context, canceled) {
11621173
}
11631174
}
11641175

1176+
if (self.blockList?.check(address, `ipv${addressType}`)) {
1177+
const ex = new ERR_IP_BLOCKED(address);
1178+
ArrayPrototypePush(context.errors, ex);
1179+
self.emit('connectionAttemptFailed', address, port, addressType, ex);
1180+
internalConnectMultiple(context);
1181+
return;
1182+
}
1183+
11651184
debug('connect/multiple: attempting to connect to %s:%d (addressType: %d)', address, port, addressType);
11661185
self.emit('connectionAttempt', address, port, addressType);
11671186

@@ -1792,8 +1811,7 @@ function Server(options, connectionListener) {
17921811
this.keepAliveInitialDelay = ~~(options.keepAliveInitialDelay / 1000);
17931812
this.highWaterMark = options.highWaterMark ?? getDefaultHighWaterMark();
17941813
if (options.blockList) {
1795-
// TODO: use BlockList.isBlockList (https://github.com/nodejs/node/pull/56078)
1796-
if (!(options.blockList instanceof module.exports.BlockList)) {
1814+
if (!module.exports.BlockList.isBlockList(options.blockList)) {
17971815
throw new ERR_INVALID_ARG_TYPE('options.blockList', 'net.BlockList', options.blockList);
17981816
}
17991817
this.blockList = options.blockList;
Lines changed: 68 additions & 0 deletions

0 commit comments

Comments
 (0)