Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ba9d539

Browse filesBrowse files
theanarkhruyadorno
authored andcommitted
dgram: support blocklist in udp
PR-URL: #56087 Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent b1cec2c commit ba9d539
Copy full SHA for ba9d539

File tree

Expand file treeCollapse file tree

3 files changed

+92
-1
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+92
-1
lines changed
Open diff view settings
Collapse file

‎doc/api/dgram.md‎

Copy file name to clipboardExpand all lines: doc/api/dgram.md
+7Lines changed: 7 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,13 @@ changes:
957957
* `sendBufferSize` {number} Sets the `SO_SNDBUF` socket value.
958958
* `lookup` {Function} Custom lookup function. **Default:** [`dns.lookup()`][].
959959
* `signal` {AbortSignal} An AbortSignal that may be used to close a socket.
960+
* `receiveBlockList` {net.BlockList} `receiveBlockList` can be used for discarding
961+
inbound datagram to specific IP addresses, IP ranges, or IP subnets. This does not
962+
work if the server is behind a reverse proxy, NAT, etc. because the address
963+
checked against the blocklist is the address of the proxy, or the one
964+
specified by the NAT.
965+
* `sendBlockList` {net.BlockList} `sendBlockList` can be used for disabling outbound
966+
access to specific IP addresses, IP ranges, or IP subnets.
960967
* `callback` {Function} Attached as a listener for `'message'` events. Optional.
961968
* Returns: {dgram.Socket}
962969

Collapse file

‎lib/dgram.js‎

Copy file name to clipboardExpand all lines: lib/dgram.js
+36-1Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const {
3939
ERR_BUFFER_OUT_OF_BOUNDS,
4040
ERR_INVALID_ARG_TYPE,
4141
ERR_INVALID_FD_TYPE,
42+
ERR_IP_BLOCKED,
4243
ERR_MISSING_ARGS,
4344
ERR_SOCKET_ALREADY_BOUND,
4445
ERR_SOCKET_BAD_BUFFER_SIZE,
@@ -53,6 +54,7 @@ const {
5354
_createSocketHandle,
5455
newHandle,
5556
} = require('internal/dgram');
57+
const { isIP } = require('internal/net');
5658
const {
5759
isInt32,
5860
validateAbortSignal,
@@ -97,12 +99,18 @@ let _cluster = null;
9799
function lazyLoadCluster() {
98100
return _cluster ??= require('cluster');
99101
}
102+
let _blockList = null;
103+
function lazyLoadBlockList() {
104+
return _blockList ??= require('internal/blocklist').BlockList;
105+
}
100106

101107
function Socket(type, listener) {
102108
FunctionPrototypeCall(EventEmitter, this);
103109
let lookup;
104110
let recvBufferSize;
105111
let sendBufferSize;
112+
let receiveBlockList;
113+
let sendBlockList;
106114

107115
let options;
108116
if (type !== null && typeof type === 'object') {
@@ -117,6 +125,18 @@ function Socket(type, listener) {
117125
}
118126
recvBufferSize = options.recvBufferSize;
119127
sendBufferSize = options.sendBufferSize;
128+
if (options.receiveBlockList) {
129+
if (!lazyLoadBlockList().isBlockList(options.receiveBlockList)) {
130+
throw new ERR_INVALID_ARG_TYPE('options.receiveBlockList', 'net.BlockList', options.receiveBlockList);
131+
}
132+
receiveBlockList = options.receiveBlockList;
133+
}
134+
if (options.sendBlockList) {
135+
if (!lazyLoadBlockList().isBlockList(options.sendBlockList)) {
136+
throw new ERR_INVALID_ARG_TYPE('options.sendBlockList', 'net.BlockList', options.sendBlockList);
137+
}
138+
sendBlockList = options.sendBlockList;
139+
}
120140
}
121141

122142
const handle = newHandle(type, lookup);
@@ -139,6 +159,8 @@ function Socket(type, listener) {
139159
ipv6Only: options?.ipv6Only,
140160
recvBufferSize,
141161
sendBufferSize,
162+
receiveBlockList,
163+
sendBlockList,
142164
};
143165

144166
if (options?.signal !== undefined) {
@@ -437,7 +459,9 @@ function doConnect(ex, self, ip, address, port, callback) {
437459
const state = self[kStateSymbol];
438460
if (!state.handle)
439461
return;
440-
462+
if (!ex && state.sendBlockList?.check(ip, `ipv${isIP(ip)}`)) {
463+
ex = new ERR_IP_BLOCKED(ip);
464+
}
441465
if (!ex) {
442466
const err = state.handle.connect(ip, port);
443467
if (err) {
@@ -701,6 +725,13 @@ function doSend(ex, self, ip, list, address, port, callback) {
701725
return;
702726
}
703727

728+
if (ip && state.sendBlockList?.check(ip, `ipv${isIP(ip)}`)) {
729+
if (callback) {
730+
process.nextTick(callback, new ERR_IP_BLOCKED(ip));
731+
}
732+
return;
733+
}
734+
704735
const req = new SendWrap();
705736
req.list = list; // Keep reference alive.
706737
req.address = address;
@@ -949,6 +980,10 @@ function onMessage(nread, handle, buf, rinfo) {
949980
if (nread < 0) {
950981
return self.emit('error', new ErrnoException(nread, 'recvmsg'));
951982
}
983+
if (self[kStateSymbol]?.receiveBlockList?.check(rinfo.address,
984+
rinfo.family?.toLocaleLowerCase())) {
985+
return;
986+
}
952987
rinfo.size = buf.length; // compatibility
953988
self.emit('message', buf, rinfo);
954989
}
Collapse file
+49Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const dgram = require('dgram');
5+
const net = require('net');
6+
7+
{
8+
const blockList = new net.BlockList();
9+
blockList.addAddress(common.localhostIPv4);
10+
11+
const connectSocket = dgram.createSocket({ type: 'udp4', sendBlockList: blockList });
12+
connectSocket.connect(9999, common.localhostIPv4, common.mustCall((err) => {
13+
assert.ok(err.code === 'ERR_IP_BLOCKED', err);
14+
connectSocket.close();
15+
}));
16+
}
17+
18+
{
19+
const blockList = new net.BlockList();
20+
blockList.addAddress(common.localhostIPv4);
21+
const sendSocket = dgram.createSocket({ type: 'udp4', sendBlockList: blockList });
22+
sendSocket.send('hello', 9999, common.localhostIPv4, common.mustCall((err) => {
23+
assert.ok(err.code === 'ERR_IP_BLOCKED', err);
24+
sendSocket.close();
25+
}));
26+
}
27+
28+
{
29+
const blockList = new net.BlockList();
30+
blockList.addAddress(common.localhostIPv4);
31+
const receiveSocket = dgram.createSocket({ type: 'udp4', receiveBlockList: blockList });
32+
// Hack to close the socket
33+
const check = blockList.check;
34+
blockList.check = function() {
35+
process.nextTick(() => {
36+
receiveSocket.close();
37+
});
38+
return check.apply(this, arguments);
39+
};
40+
receiveSocket.on('message', common.mustNotCall());
41+
receiveSocket.bind(0, common.localhostIPv4, common.mustCall(() => {
42+
const addressInfo = receiveSocket.address();
43+
const client = dgram.createSocket('udp4');
44+
client.send('hello', addressInfo.port, addressInfo.address, common.mustCall((err) => {
45+
assert.ok(!err);
46+
client.close();
47+
}));
48+
}));
49+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.