Support passing socket options (e.g. `reuseAddr`) to the underlying dgram socket
When creating an `Http3Server`, there is currently no way to pass options to the underlying `node:dgram` socket created internally by `Http3WebTransportServerSocket`. The socket is created with only the `type` field:
```js
// lib/serversocket.js, init()
this.socketInt = createSocket({
type: result.family === 4 ? 'udp4' : 'udp6'
})
```
Node's `dgram.createSocket()` supports additional options like `reuseAddr`, `reusePort`, `recvBufferSize`, `sendBufferSize`, and `signal` — none of which can be configured through the `Http3Server` constructor today.
## Why this matters
The most impactful missing option is `reuseAddr: true` (`SO_REUSEADDR`). Without it, after a server shuts down (or is killed), the OS may not immediately release the UDP port. A new server instance trying to bind the same port can fail with `EADDRINUSE`, even though no process is actively using it.
This is especially problematic in development workflows where servers are frequently restarted (e.g. via `tsx watch`, `nodemon`, or similar file-watching tools). It also affects production graceful-restart scenarios where a new instance must bind the same port before the old instance has fully terminated.
On macOS in particular, the port can remain unavailable for a noticeable window after process exit when `SO_REUSEADDR` is not set.
## Proposed API
Allow passing through `dgram.SocketOptions` (or a subset) via the existing `Http3Server` / `Http3WebTransportServerSocket` constructor args:
```js
const server = new Http3Server({
host: '0.0.0.0',
port: 3001,
cert: '...',
privKey: '...',
// new: forward to dgram.createSocket()
socketOptions: {
reuseAddr: true,
},
});
```
And in `Http3WebTransportServerSocket.init()`:
```js
this.socketInt = createSocket({
type: result.family === 4 ? 'udp4' : 'udp6',
reuseAddr: this.args?.socketOptions?.reuseAddr ?? false,
// ...other forwarded options
})
```
## Workaround
There is currently no clean workaround. The `socketInt` property is set asynchronously inside `init()` after a DNS lookup, so it cannot be intercepted and replaced from outside. The only option is patching the library source or using `patch-package`.
0 条评论