Skip to content

Conversation

@adamziel
Copy link
Collaborator

@adamziel adamziel commented Dec 5, 2025

Motivation

Before this PR, the gethostbyname() PHP function always returns either an internal IP address on success, or an unchanged hostname on failure. That's because Emscripten's default DNS implementation doesn't perform real lookups.

This PR enables actual DNS resolution for PHP-WASM running in Node.js via Node's dns
module. When PHP code calls gethostbyname('wordpress.org'), it now resolves and returns
the real IP address.

Implementation details

The implementation works similarly to FileLockManager:

phpwasm-emscripten-library-dns-lookup-for-node.js defines a new build-time JavaScript library linked with PHP.wasm. It overrides the __emscripten_lookup_name shipped by Emscripten with a custom callback that calls PHPLoader.syscalls.gethostbyname() to resolve the IP.

PHPLoader.syscalls is an object passed to loadNodeRuntime() via options.emscriptenOptions. It's an object that, for now, defines a single method: gethostbyname().

Even though you may pass an actual object instance, we create the instance in the parent worker and call gethostbyname() using a Comlink proxy. This is because require('dns').lookup() is asynchronous in Node. JSPI builds can easily await the returned value, but Asyncify builds can't. Not without spending a dozen hours tweaking the ASYNCIFY_ONLY list in the PHP compile Dockerfile. Therefore, we use a synchronous Comlink proxy to turn an asynchronous gethostbyname() call into a synchronous one in Asyncify builds.

Test plan

CI. See the tests shipped with this PR, confirm they pass and make sense.

cc @bcotrim @fredrikekelund

@adamziel adamziel changed the title [PHP] gethostbyname support for Node builds [PHP] gethostbyname – native DNS resolution in Node.js builds Dec 5, 2025
@adamziel adamziel marked this pull request as ready for review December 6, 2025 00:05
*/
async gethostbyname(hostname: string): Promise<string> {
const { address } = await lookup(hostname, {
family: 4,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

perhaps we could support ipv6 while we're at it. Or merge this as is and add v6 support in a follow-up pr

Resolved conflicts by prioritizing trunk's wasm files and removing syscalls-related code that was removed in trunk.
@adamziel adamziel force-pushed the gethostbyname-support branch from 7fc9ada to 4332dd2 Compare January 20, 2026 00:47
@adamziel adamziel requested a review from a team as a code owner January 20, 2026 00:47
Removed all references to SyscallsForNode that were deleted in trunk during the merge. This includes:
- Removed SyscallsForNode type from load-runtime.ts
- Deleted syscalls-test-worker.ts test file
- Removed syscalls field and useSyscalls method from worker classes
- Removed syscallsPort parameters from handler functions
@adamziel adamziel merged commit 2db97ab into trunk Jan 20, 2026
33 checks passed
@adamziel adamziel deleted the gethostbyname-support branch January 20, 2026 11:07
@adamziel
Copy link
Collaborator Author

@brandonpayton this may impact your work on the filesystem as it also introduces a central syscalls handler like yours. Let's merge the two.

@brandonpayton
Copy link
Member

@brandonpayton this may impact your work on the filesystem as it also introduces a central syscalls handler like yours. Let's merge the two.

@adamziel sounds good! I plan to account for that in the big rebase I'm doing today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants