-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
dgram: implement socket.bind({ fd }) #21745
Conversation
db24841
to
6d026ad
Compare
lib/dgram.js
Outdated
@@ -97,19 +98,27 @@ function newHandle(type, lookup) { | |||
throw new ERR_SOCKET_BAD_TYPE(); | |||
} | |||
|
|||
// Follow the net.js module and ignore fd if it's not a valid number. | |||
function isPossibleValidFD(fd) { | |||
return typeof fd === 'number' && fd > 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
&& isFinite(fd)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or follow the net.js and use validateInt32
. I will change it.
doc/api/dgram.md
Outdated
@@ -177,6 +178,11 @@ system will attempt to listen on all addresses. Once binding is | |||
complete, a `'listening'` event is emitted and the optional `callback` | |||
function is called. | |||
|
|||
The `options` object may contain an `fd` property. When a `fd` greater |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A nit: I am not sure what is correct: an `fd`
or a `fd`
, but these two fragments need to be unified)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed :)
lib/dgram.js
Outdated
function isPossibleValidFD(fd) { | ||
let valid = true; | ||
try { | ||
validateInt32(fd, 'fd', 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use isInt32
instead. That does exactly what is necessary here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your advice. As we need to make sure that the fd
is greater than 0
, I use isUint32
directly.
Another test is added that it should return errno
when the type of fd is not "UDP"
.
@nodejs/dgram PTAL |
Ping @nodejs/dgram |
lib/dgram.js
Outdated
function _createSocketHandle(address, port, addressType, fd, flags) { | ||
// Opening an existing fd is not supported for UDP handles. | ||
assert(typeof fd !== 'number' || fd < 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this used to throw, but now the logic returns an error, so it's a change in API. Given that we export this, it would be a semver-major change.
I'm a bit lost on why we need this _createSocketHandle
function at all. Does anyone know? If it's useful, we should remove the _
. If it's not and it's useful for tests only, we should move it to internals
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be in internals
. It's hard to say if there is any ecosystem usage though. It's used in core by the cluster
module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, _createSocketHandle
is used in cluster
module to create a handle from a master process and handles like these will be shared with worker processes.
Maybe we can remove _
in other PRs as it's also named like _createServerHandle
in the net
module.
lib/dgram.js
Outdated
const { UV_UDP_REUSEADDR } = process.binding('constants').os; | ||
const TTYWrap = process.binding('tty_wrap'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not fond of UDP requiring TTY. Maybe we should move that guessHandleType
somewhere else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe move the guessHandleType
into lib/internal/util.js
or lib/internal/net.js
?
lib/dgram.js
Outdated
if (err) { | ||
handle.close(); | ||
return err; | ||
if (isUint32(fd)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small detail, but I don't think we want a uint32, but rather an int32 that is not negative.
lib/dgram.js
Outdated
return; | ||
} | ||
|
||
if (!state.handle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit: can braces be included with the conditional's multi-line body?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/dgram.js
Outdated
@@ -171,6 +194,44 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) { | |||
return this; | |||
} | |||
|
|||
// Open an existing fd instead. | |||
if (port !== null && typeof port === 'object' && | |||
isInt32(port.fd) && port.fd > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The indentation is off here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/parallel/test-dgram-bind-fd.js
Outdated
|
||
socket.on('message', common.mustCall((data) => { | ||
assert.strictEqual(data.toString('utf8'), String(fd)); | ||
setTimeout(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this timeout and the one below for the receiver?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. It's unnecessary here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The receiver one is needed because calling close
directly would prevent the message from being sent.
I use process.nextTick
instead of the setTimeout
as I think it's more precise here.
bf50fde
to
21f3515
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTN
CI: https://ci.nodejs.org/job/node-test-pull-request/16074/
|
@mscdex I'm ok in landing it as a minor if there is no ecosystem usage of this. That might truly be the case. |
The test that failed before on Jenkins seems unrelated (see #22041). |
@nodejs/tsc PTAL, this need another LGTM. |
const assert = require('assert'); | ||
const cluster = require('cluster'); | ||
const dgram = require('dgram'); | ||
const UDP = process.binding('udp_wrap').UDP; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor nit: const { UDP } = process.binding('udp_wrap');
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Green CI and two TSC approvals on a semver-major means this can land. Since TSC was only pinged 12 hours ago, it might be a good idea to leave it open for the weekend to give people a chance to weigh in before landing. (But that is not required.) |
dgram: Implement binding an existing `fd`. Allow pass a `fd` property to `socket.bind()` in dgram. src: Add `UDPWrap::Open` Fixes: nodejs#14961
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. It might make sense to expose fd
now, but don't worry about it in this PR.
CI: https://ci.nodejs.org/job/node-test-pull-request/16209/ (last before landing) |
Landed in 2bea9ce |
Thanks @oyyd for your first contribution to Node.js Core! 🎉 |
@mcollina Thanks! |
dgram: Implement binding an existing
fd
. Allow passing afd
property tosocket.bind()
in dgram.src: Add
UDPWrap::Open
.Cluster is also considered. All related tests are ignored on windows.
Fixes: #14961
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes