You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Core wasm32-wasip1 modules cannot import component-model wasi:sockets, so language runtimes such as CPython need a small raw TCP ABI to use their own TLS and protocol stacks.
Design
Adds the versioned core import wippy:runtime/socket@0.1.0 with connect, send, recv, and close.
Uses the existing netapi.Service. The shared secure service owns socket.connect, socket.private_ip, selected-overlay routing, remote DNS behavior, and fail-closed lookup. The WASM host does not resolve overlays or invent permissions.
Stores connections in the executing WASM instance resource table. Handles and capacity are isolated per instance; instance close destroys all remaining connections.
Uses limits.max_open_sockets and limits.socket_timeout_ms with safe defaults. Connect, send, and receive are bounded; cancellation closes the connection even when an overlay connection does not implement deadlines.
Keeps synchronous raw calls. No asyncify transformation is added to large core guests.
The function/process option pipeline remains the only overlay selector: per-call options.network, entry options, and the application default are resolved into the call frame before execution.
Lifecycle prerequisite
Depends on wippyai/wasm-runtime#15, now merged as e9b09350cd7c. That change gives every core/component instance an owned host-resource table and drains component resource destructors before closing core modules.
Existing pool retirement remains the lifecycle owner: update, delete, dynamic uninstall, and manager stop call pool stop; pool stop closes its processes; process close closes the instance; instance close drops the connections.
WASI sockets correction
This also folds #611 into the same WASM assembly: finish-connect and accept now return one record plus the network error, matching canonical ABI lowering. A committed Rust wasm32-wasip2 fixture imports the stock socket interfaces and must bind in CI.
Verification
Touched-package tests: green.
Touched-package lint: 0 issues.
Targeted race suite across network, core sockets, WASI sockets, engine, function/process managers, and boot registration: green.
Resource lifecycle tests cover destructor execution, instance isolation, idempotent close, warm-process close, foreign-handle rejection, per-instance limits, overlay routing, cancellation, and configured timeout against a connection that ignores deadlines.
Repository-wide tests passed except the unrelated RabbitMQ readiness integration (service/queue/amqp). Repository-wide lint reports four existing findings in untouched registry/bootconfig files.
Proof that the wasm guest obeys the same network rules as Lua
A guest was previously dialed with a plain net.Dialer, so it ignored the network options every host-side caller obeys. In an application routed through an overlay that is a leak: the guest reaches clearnet, exposing the DNS lookup and the target address the overlay exists to hide.
The dial now resolves exactly as runtime/lua/modules/httpclient and service/http/client do — netapi.GetDefaultNetwork on the frame, which already carries the effective value after per-call options.network, per-entry meta.options.network and the app default have been merged. The registry is read from the call context, not captured at boot, so a guest follows the network its own frame selected.
Rule-by-rule
Rule
Lua / HTTP dispatcher
wasm guest (this PR)
Overlay selection source
netapi.GetDefaultNetwork(ctx)
same
network.select permission
required
required
Overlay requested, registry missing
refused, no clearnet fallback
refused, no clearnet fallback
Local DNS for overlay targets
skipped (would leak the hostname)
skipped
Private-address policy
http_client.private_ip
same
Test output
=== RUN TestOverlayNetworkIsUsedWhenSelected
--- PASS: TestOverlayNetworkIsUsedWhenSelected (0.00s)
=== RUN TestOverlayRequestedWithoutRegistryIsRefused
refused: overlay network "network:tor" requested but no network registry is configured
--- PASS: TestOverlayRequestedWithoutRegistryIsRefused (0.00s)
=== RUN TestPrivateAddressNeedsPermission
refused: not allowed: private IP 127.0.0.1
--- PASS: TestPrivateAddressNeedsPermission (0.00s)
=== RUN TestOverlaySelectionNeedsPermission
refused: not allowed: network network:tor
--- PASS: TestOverlaySelectionNeedsPermission (0.00s)
ok github.com/wippyai/runtime/runtime/wasm/host/wippy/hosts/coresock
TestOverlayNetworkIsUsedWhenSelected asserts the overlay dialer is the one actually called, with the address it received; TestOverlaySelectionNeedsPermission asserts that when the permission is denied the overlay dialer is not called and the dial fails, rather than being downgraded.
Also in this push
The two lint findings from the earlier run are fixed: a fieldalignment report on an anonymous struct (replaced with explicit registration calls) and a British spelling flagged by misspell. ./runtime/wasm/... and ./boot/components/runtime/... are green, and golangci-lint reports 0 issues for the touched packages.
wolfy-j
changed the title
feat(wasm): outbound TCP for core modules (wippy:sock/tcp)
feat(wasm): instance-owned outbound TCP for core modules
Aug 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Core
wasm32-wasip1modules cannot import component-modelwasi:sockets, so language runtimes such as CPython need a small raw TCP ABI to use their own TLS and protocol stacks.Design
wippy:runtime/socket@0.1.0withconnect,send,recv, andclose.netapi.Service. The shared secure service ownssocket.connect,socket.private_ip, selected-overlay routing, remote DNS behavior, and fail-closed lookup. The WASM host does not resolve overlays or invent permissions.limits.max_open_socketsandlimits.socket_timeout_mswith safe defaults. Connect, send, and receive are bounded; cancellation closes the connection even when an overlay connection does not implement deadlines.The function/process option pipeline remains the only overlay selector: per-call
options.network, entry options, and the application default are resolved into the call frame before execution.Lifecycle prerequisite
Depends on wippyai/wasm-runtime#15, now merged as
e9b09350cd7c. That change gives every core/component instance an owned host-resource table and drains component resource destructors before closing core modules.Existing pool retirement remains the lifecycle owner: update, delete, dynamic uninstall, and manager stop call pool stop; pool stop closes its processes; process close closes the instance; instance close drops the connections.
WASI sockets correction
This also folds #611 into the same WASM assembly:
finish-connectandacceptnow return one record plus the network error, matching canonical ABI lowering. A committed Rustwasm32-wasip2fixture imports the stock socket interfaces and must bind in CI.Verification
service/queue/amqp). Repository-wide lint reports four existing findings in untouched registry/bootconfig files.