This commit is contained in:
2026-08-18 18:11:28 -04:00
parent 0e9a650fa2
commit bbaf47028f
259 changed files with 0 additions and 0 deletions
@@ -0,0 +1,256 @@
/**
* POSIX socket-FD bridge helpers (logical dup, shutdown, sendmsg prep).
* Takes the guest ctx; no executeKernel closure.
*/
import {
bareOsEnsureSocketSlotAliasKeys,
bareOsParseSendmsgScmRights,
bareOsScmRightsMaxFds,
wantPosixSocketScmRights
} from './bare-os-socket-scm-rights.js'
import {
bareOsFlattenSendmsgIovs,
bareOsSendmsgAncillaryRejectReason
} from './bare-os-posix-syscall-helpers.js'
/**
* @param {Record<string, unknown>} c ctx
* @param {number} srcFd
* @returns {number | null}
*/
export function bareOsDupLogicalFdForScm(c, srcFd) {
const k = String(Number(srcFd) >>> 0)
const bridge = c.bareOsSocketBridgeByFd
const slot = bridge && typeof bridge === 'object' ? bridge[k] : null
if (slot && typeof slot === 'object') {
if (
slot.state === 'listening' ||
slot.state === 'created' ||
slot.state === 'bound'
) {
return null
}
bareOsEnsureSocketSlotAliasKeys(slot, k)
const st = c.bareOsPosixFdSimState
const newFd = st.nextFd++
if (st.nextFd > 65530) return null
const nk = String(newFd)
if (
!c.bareOsSocketBridgeByFd ||
typeof c.bareOsSocketBridgeByFd !== 'object'
)
return null
c.bareOsSocketBridgeByFd[nk] = slot
slot.aliasKeys.add(nk)
const targ = c.bareOsLogicalFds[k] || 'bare-os-socket-bridge:dup'
c.bareOsRegisterLogicalFd(newFd, String(targ))
const fl = c.bareOsLogicalFdFlags[k]
if (typeof fl === 'number') c.bareOsLogicalFdFlags[nk] = fl
return newFd
}
const target = c.bareOsLogicalFds[k]
if (!target) return null
const st = c.bareOsPosixFdSimState
const newFd = st.nextFd++
if (st.nextFd > 65530) return null
const nk = String(newFd)
c.bareOsRegisterLogicalFd(newFd, String(target))
const fl = c.bareOsLogicalFdFlags[k]
if (typeof fl === 'number') c.bareOsLogicalFdFlags[nk] = fl
return newFd
}
/**
* @param {Record<string, unknown>} c ctx
* @param {number} fd
*/
export async function bareOsShutdownSocketBridgeFd(c, fd, howMaybe) {
const k = String(Number(fd) >>> 0)
const bridge = c.bareOsSocketBridgeByFd
if (!bridge || typeof bridge !== 'object') {
return {
ok: false,
op: 'shutdown',
code: 'EINVAL',
errnoHint: 'EINVAL',
note: 'shutdown: not a bridge fd'
}
}
const slot = bridge[k]
if (!slot || typeof slot !== 'object') {
return {
ok: false,
op: 'shutdown',
code: 'EINVAL',
errnoHint: 'EINVAL',
note: 'shutdown: not a bridge fd'
}
}
bareOsEnsureSocketSlotAliasKeys(slot, k)
const howN = Number(howMaybe)
const how = Number.isFinite(howN)
? Math.min(2, Math.max(0, Math.floor(howN)))
: 2
const tcpHalf =
slot.transport === 'tcp' &&
slot.state === 'connected' &&
slot.sock &&
(how === 0 || how === 1)
if (tcpHalf) {
if (how === 0) slot.tcpShutRd = true
if (how === 1) {
slot.tcpShutWr = true
try {
slot.sock.end?.()
} catch (_) {}
}
return {
ok: true,
op: 'shutdown',
bridge: true,
posixAlignment: 'partial',
how,
note:
how === 0
? 'TCP bridge: SHUT_RD — recv drains then EOF; poll marks readable when queue drained after peer FIN.'
: 'TCP bridge: SHUT_WR — further send returns EPIPE-shaped failure.'
}
}
delete bridge[k]
c.bareOsUnregisterLogicalFd(fd)
slot.aliasKeys.delete(k)
if (slot.aliasKeys.size > 0) {
return {
ok: true,
op: 'shutdown',
bridge: true,
posixAlignment: 'partial',
scmRightsRefDup: true
}
}
if (slot.state === 'listening' && slot.server) {
try {
slot.server.close?.()
} catch (_) {}
slot.server = null
if (Array.isArray(slot.acceptQueue)) {
for (const w of slot.acceptQueue) {
try {
w.sock?.destroy?.()
} catch (_) {}
}
slot.acceptQueue = []
}
slot.state = 'closed'
return {
ok: true,
op: 'shutdown',
bridge: true,
posixAlignment: 'partial'
}
}
if (
(slot.state === 'connected' || slot.state === 'udp_bound') &&
slot.sock
) {
try {
slot.sock.destroy?.()
} catch (_) {}
try {
await slot.sock.close?.()
} catch (_) {}
slot.state = 'closed'
return {
ok: true,
op: 'shutdown',
bridge: true,
posixAlignment: 'partial'
}
}
return {
ok: false,
op: 'shutdown',
code: 'ENOTSUP',
errnoHint: 'ENOTSUP',
posixAlignment: 'ENOTSUP',
note: 'shutdown: bridge fd not connected, bound, or listening.'
}
}
/**
* @param {Record<string, unknown>} c ctx (`c.env` is the guest shell env)
* @param {Record<string, unknown>} args
*/
export function prepareBridgeSendmsg(c, args) {
const a =
args && typeof args === 'object'
? /** @type {Record<string, unknown>} */ (args)
: {}
const env =
c && c.env && typeof c.env === 'object'
? /** @type {Record<string, string | undefined>} */ (c.env)
: {}
const scmOn = wantPosixSocketScmRights(env)
const parsed = bareOsParseSendmsgScmRights(
a,
scmOn,
bareOsScmRightsMaxFds(env)
)
if (!parsed.ok) {
return {
ok: false,
err: {
ok: false,
op: 'sendmsg',
code: 'ENOTSUP',
errnoHint: 'ENOTSUP',
posixAlignment: 'ENOTSUP',
ancillaryReject: parsed.reject,
note: 'sendmsg: ancillary control rejected (see ancillaryReject).'
}
}
}
if (!scmOn) {
const leg = bareOsSendmsgAncillaryRejectReason(a)
if (leg) {
return {
ok: false,
err: {
ok: false,
op: 'sendmsg',
code: 'ENOTSUP',
errnoHint: 'ENOTSUP',
posixAlignment: 'ENOTSUP',
ancillaryReject: leg,
note: 'sendmsg: ancillary control messages (cmsgs/control/controllen/msgHdr.*) are unsupported on the socket FD bridge without BARE_OS_POSIX_SOCKET_SCM_RIGHTS; use payload-only send or bare IPC.'
}
}
}
}
/** @type {{ from: number; to: number }[]} */
const scmRightsLocalDup = []
for (const src of parsed.fds) {
const to = bareOsDupLogicalFdForScm(c, src)
if (to == null) {
return {
ok: false,
err: {
ok: false,
op: 'sendmsg',
code: 'EBADF',
errnoHint: 'EBADF',
posixAlignment: 'ENOTSUP',
note: 'sendmsg: SCM_RIGHTS logical dup failed (unknown fd, idle/listen/bound socket, or FD budget).'
}
}
}
scmRightsLocalDup.push({ from: Number(src) >>> 0, to })
}
const f = bareOsFlattenSendmsgIovs(a)
if (!f.ok) return { ok: false, err: f.err }
return {
ok: true,
payload: f.buf,
scmRightsLocalDup
}
}