fix(ext/node): node compatibility issue missing fd in createServer callback socket object (#27789)

This commit is contained in:
Muthuraj Ramalingakumar 2025-02-25 21:52:18 -08:00 committed by Ryan Dahl
parent abdc08360c
commit 2ddaafd762
3 changed files with 34 additions and 10 deletions

View file

@ -5,6 +5,7 @@ const {
BadResourcePrototype,
InterruptedPrototype,
internalRidSymbol,
internalFdSymbol,
createCancelHandle,
} = core;
import {
@ -99,13 +100,17 @@ class Conn {
#readable;
#writable;
constructor(rid, remoteAddr, localAddr) {
constructor(rid, remoteAddr, localAddr, fd) {
ObjectDefineProperty(this, internalRidSymbol, {
__proto__: null,
enumerable: false,
value: rid,
});
ObjectDefineProperty(this, internalFdSymbol, {
__proto__: null,
enumerable: false,
value: fd,
});
this.#rid = rid;
this.#remoteAddr = remoteAddr;
this.#localAddr = localAddr;
@ -211,8 +216,8 @@ class UpgradedConn extends Conn {
class TcpConn extends Conn {
#rid = 0;
constructor(rid, remoteAddr, localAddr) {
super(rid, remoteAddr, localAddr);
constructor(rid, remoteAddr, localAddr, fd) {
super(rid, remoteAddr, localAddr, fd);
ObjectDefineProperty(this, internalRidSymbol, {
__proto__: null,
enumerable: false,
@ -278,12 +283,12 @@ class Listener {
}
this.#promise = promise;
if (this.#unref) core.unrefOpPromise(promise);
const { 0: rid, 1: localAddr, 2: remoteAddr } = await promise;
const { 0: rid, 1: localAddr, 2: remoteAddr, 3: fd } = await promise;
this.#promise = null;
if (this.addr.transport == "tcp") {
localAddr.transport = "tcp";
remoteAddr.transport = "tcp";
return new TcpConn(rid, remoteAddr, localAddr);
return new TcpConn(rid, remoteAddr, localAddr, fd);
} else if (this.addr.transport == "unix") {
return new UnixConn(
rid,

View file

@ -46,6 +46,8 @@ use crate::resolve_addr::resolve_addr_sync;
use crate::tcp::TcpListener;
use crate::NetPermissions;
pub type Fd = u32;
#[derive(Serialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TlsHandshakeInfo {
@ -165,7 +167,7 @@ pub(crate) fn accept_err(e: std::io::Error) -> NetError {
pub async fn op_net_accept_tcp(
state: Rc<RefCell<OpState>>,
#[smi] rid: ResourceId,
) -> Result<(ResourceId, IpAddr, IpAddr), NetError> {
) -> Result<(ResourceId, IpAddr, IpAddr, Option<Fd>), NetError> {
let resource = state
.borrow()
.resource_table
@ -180,6 +182,14 @@ pub async fn op_net_accept_tcp(
.try_or_cancel(cancel)
.await
.map_err(accept_err)?;
let mut _fd_raw: Option<Fd> = None;
#[cfg(not(windows))]
{
use std::os::fd::AsFd;
use std::os::fd::AsRawFd;
let fd = tcp_stream.as_fd();
_fd_raw = Some(fd.as_raw_fd() as u32);
}
let local_addr = tcp_stream.local_addr()?;
let remote_addr = tcp_stream.peer_addr()?;
@ -187,7 +197,12 @@ pub async fn op_net_accept_tcp(
let rid = state
.resource_table
.add(TcpStreamResource::new(tcp_stream.into_split()));
Ok((rid, IpAddr::from(local_addr), IpAddr::from(remote_addr)))
Ok((
rid,
IpAddr::from(local_addr),
IpAddr::from(remote_addr),
_fd_raw,
))
}
#[op2(async)]

View file

@ -27,6 +27,8 @@
// TODO(petamoriken): enable prefer-primordials for node polyfills
// deno-lint-ignore-file prefer-primordials
import { core } from "ext:core/mod.js";
const { internalFdSymbol } = core;
import { notImplemented } from "ext:deno_node/_utils.ts";
import { unreachable } from "ext:deno_node/_util/asserts.ts";
import { ConnectionWrap } from "ext:deno_node/internal_binding/connection_wrap.ts";
@ -141,6 +143,10 @@ export class TCP extends ConnectionWrap {
}
}
get fd() {
return this[kStreamBaseField]?.[internalFdSymbol];
}
/**
* Opens a file descriptor.
* @param fd The file descriptor to open.
@ -221,7 +227,6 @@ export class TCP extends ConnectionWrap {
const address = listener.addr as Deno.NetAddr;
this.#address = address.hostname;
this.#port = address.port;
this.#listener = listener;
// TODO(kt3k): Delays the accept() call 2 ticks. Deno.Listener can't be closed
@ -458,7 +463,6 @@ export class TCP extends ConnectionWrap {
// Reset the backoff delay upon successful accept.
this.#acceptBackoffDelay = undefined;
const connectionHandle = new TCP(socketType.SOCKET, connection);
this.#connections++;