Skip to content

Commit

Permalink
fix(ext/net): node compatibility issue missing fd in createServer cal…
Browse files Browse the repository at this point in the history
…lback socket object

This PR will address the node compatibility issue where, the callback socket
object in net.createServer is missing a fd in socket._handle

fixes: #27788
  • Loading branch information
muthu90tech committed Jan 23, 2025
1 parent ab18dac commit 0f61f5f
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 7 deletions.
16 changes: 11 additions & 5 deletions ext/net/01_net.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ class Conn {

#readable;
#writable;
#fd = -1;

constructor(rid, remoteAddr, localAddr) {
constructor(rid, remoteAddr, localAddr, fd) {
ObjectDefineProperty(this, internalRidSymbol, {
__proto__: null,
enumerable: false,
Expand All @@ -109,12 +110,17 @@ class Conn {
this.#rid = rid;
this.#remoteAddr = remoteAddr;
this.#localAddr = localAddr;
this.#fd = fd;
}

get remoteAddr() {
return this.#remoteAddr;
}

get fd() {
return this.#fd;
}

get localAddr() {
return this.#localAddr;
}
Expand Down Expand Up @@ -211,8 +217,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,
Expand Down Expand Up @@ -278,12 +284,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,
Expand Down
2 changes: 2 additions & 0 deletions ext/net/lib.deno_net.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ declare namespace Deno {

readonly readable: ReadableStream<Uint8Array>;
readonly writable: WritableStream<Uint8Array>;

readonly fd: number;
}

/** @category Network */
Expand Down
10 changes: 8 additions & 2 deletions ext/net/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::cell::RefCell;
use std::net::Ipv4Addr;
use std::net::Ipv6Addr;
use std::net::SocketAddr;
use std::os::fd::AsFd;
use std::os::fd::AsRawFd;
use std::rc::Rc;
use std::str::FromStr;

Expand Down Expand Up @@ -46,6 +48,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 {
Expand Down Expand Up @@ -165,7 +169,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, Fd), NetError> {
let resource = state
.borrow()
.resource_table
Expand All @@ -180,14 +184,16 @@ pub async fn op_net_accept_tcp(
.try_or_cancel(cancel)
.await
.map_err(accept_err)?;
let fd = tcp_stream.as_fd();
let fd_raw = fd.as_raw_fd() as u32;
let local_addr = tcp_stream.local_addr()?;
let remote_addr = tcp_stream.peer_addr()?;

let mut state = state.borrow_mut();
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)]
Expand Down
5 changes: 5 additions & 0 deletions ext/node/polyfills/internal_binding/tcp_wrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export class TCP extends ConnectionWrap {

#closed = false;
#acceptBackoffDelay?: number;
fd = -1;

/**
* Creates a new TCP class instance.
Expand Down Expand Up @@ -127,6 +128,10 @@ export class TCP extends ConnectionWrap {

super(provider, conn);

if (conn?.fd) {
this.fd = conn.fd;
}

// TODO(cmorten): the handling of new connections and construction feels
// a little off. Suspect duplicating in some fashion.
if (conn && provider === providerType.TCPWRAP) {
Expand Down

0 comments on commit 0f61f5f

Please sign in to comment.