Raw TCP relay for guest egress beyond port 80#358
Merged
Conversation
…shim The fetch network adapter only intercepts port 80 (parsed as HTTP and replayed via fetch). Everything else was RST'd. This adds a second tcp-connection bus listener that bridges any other destination port straight to a Node net.Socket in the renderer — no extra process, no WebSocket relay, no new dependencies. - net/tcp-relay.ts: hook v86 tcp-connection, accept SYN synchronously, open a real socket to conn.psrc:conn.sport, buffer until connect, pipe both directions, tear down on either side closing. Loopback, link-local and multicast are refused; the rest of RFC1918 is left reachable so the guest can still talk to LAN devices. - net/dns-shim.ts: dns_method is now "doh" so the guest gets real IPs for the relay to dial, but Cloudflare can't answer single-label names like "windows95" or the NNN.external localhost magic. The shim wraps global fetch, spots /dns-query POSTs for those names, and answers with the same 192.168.87.1 placeholder the static resolver used to hand out — the port-80 fetch path then takes over via the Host header exactly as before. - emulator.tsx: wire both in next to the SMB hook; set dns_method. - debug-harness.ts: WIN95_PROBE_RUN/_RUN_AFTER/_RUN_WAIT to type an arbitrary command into Start→Run (used to e2e-test the relay with telnet against a host echo server).
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What
Let the Win95 guest open real TCP connections to ports other than 80. The fetch network adapter only ever accepted port-80 SYNs (parsing the payload as HTTP and replaying it via
fetch()); anything else was reset. This adds a secondtcp-connectionbus listener in the renderer that bridges every other destination straight to a Nodenet.Socket— no extra process, no WebSocket/Wisp relay, no new dependencies.How
src/renderer/net/tcp-relay.ts— accept the SYN synchronously (v86 RSTs otherwise),net.connecttoconn.psrc:conn.sport, buffer guest bytes until the upstream connects, then pipe both ways. Loopback / link-local / multicast are refused so guest software can't poke host services or cloud metadata; the rest of RFC1918 is intentionally left reachable so LAN FTP/telnet/etc keep working. Ports 80 and 139 stay with the existing fetch and SMB handlers.src/renderer/net/dns-shim.ts—net_device.dns_methodis now"doh"so the guest resolves real IPs the relay can dial. Cloudflare can't answer single-label names likewindows95or theNNN.externallocalhost magic, so this shim wraps globalfetch, spots/dns-queryPOSTs for those names, and answers with the same192.168.87.1placeholder the static resolver used to hand out — the port-80 fetch path then takes over via the Host header exactly as before.emulator.tsx— wire both in alongside the SMB hook; setdns_method.debug-harness.ts—WIN95_PROBE_RUN/_RUN_AFTER/_RUN_WAITto type an arbitrary command into Start → Run (used for the e2e test below).Tested
npm run tscclean. End-to-end: booted the guest under the probe harness, rantelnet 192.168.0.128 7777against a host-side echo server — relay opened the socket, server received the typedhi-from-win95keystrokes, and the guest's Telnet window rendered the server banner (bidirectional).http://windows95still serves the bundled static site via the DNS shim.Notes
TLS from the guest will tunnel but modern servers reject Win95-era cipher suites, so 443 connecting ≠ HTTPS working. Plaintext protocols (FTP, telnet, IRC, POP3, gopher) are the realistic win here.