Skip to content

Real DNS resolution for getaddrinfo under -sNODERAWSOCKETS - #27693

Merged
guybedford merged 9 commits into
emscripten-core:mainfrom
guybedford:noderawsockets-dns
Sep 16, 2026
Merged

guybedford merged 9 commits into
emscripten-core:mainfrom
guybedford:noderawsockets-dns

Conversation

@guybedford

@guybedford guybedford commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

This gives getaddrinfo() real name resolution under -sNODERAWSOCKETS. Split out from #27182, which also added a new asynchronous DNS API; this PR is only the change to the existing blocking API, allowing any async API work to follow separately.

Previously every hostname resolved to a fake 172.29.x.x address, which is fine for the websocket proxy transport but not for real Node.js sockets, where the address has to be connectable.

  • Hostnames resolve via node:dns (which honors the host's /etc/hosts). The lookup is asynchronous, so getaddrinfo blocks by returning a Promise where the calling stack can wait on it: a sync-proxied pthread (PROXY_SYNC_ASYNC, e.g. main() under PROXY_TO_PTHREAD), or ASYNCIFY/JSPI by suspending through Asyncify.handleAsync, which also holds a runtime keepalive so a user callback completing mid-lookup does not exit the runtime. Numeric addresses and errors still return synchronously, so JSPI does not pay a microtask on those.
  • Where there is no stack that can wait (the event-loop thread itself), a hostname returns EAI_AGAIN without starting a lookup.
  • Results may now be an addrinfo linked list (multiple DNS records, AF_UNSPEC), and freeaddrinfo walks the whole chain.

Everything is gated on NODERAWSOCKETS; without it getaddrinfo is unchanged.

Implementation-wise getaddrinfo keeps its existing body and returns either an EAI_* code or a Promise of one. The pthread proxy receive side now accepts a synchronous value from a PROXY_SYNC_ASYNC function (Promise.resolve(rtn).then(...)), so no wrapper is needed for the sync paths.

Tested with test_noderawsockets_dns (numeric, EAI_AGAIN single-threaded), and test_noderawsockets_dns_blocking{,_asyncify,_jspi} (multi-address lists across families, and a timer firing during the lookup under EXIT_RUNTIME).

Made with AI assistance under my review

Comment thread src/lib/libsockfs_node.js Outdated
@guybedford
guybedford force-pushed the noderawsockets-dns branch 2 times, most recently from 6df784b to 475c8fc Compare September 16, 2026 05:57
Comment thread src/lib/libcore.js Outdated
Comment thread src/lib/libcore.js Outdated
Comment thread src/lib/libcore.js Outdated

@sbc100 sbc100 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Much better.

Comment thread ChangeLog.md Outdated
/etc/hosts entries (read through the emscripten FS) resolve synchronously,
other hostnames resolve via node:dns, blocking where the calling stack can
wait (a proxied pthread via PROXY_SYNC_ASYNC, ASYNCIFY/JSPI by suspending)
and returning EAI_AGAIN otherwise. Results may be a linked list, which
freeaddrinfo now frees in full.
@guybedford
guybedford enabled auto-merge (squash) September 16, 2026 22:11
@guybedford
guybedford merged commit e0e87f5 into emscripten-core:main Sep 16, 2026
42 checks passed
@guybedford
guybedford deleted the noderawsockets-dns branch September 17, 2026 01:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants