Emerging from the de-vendoring review on #25 (the lann/iroh#2 discussion): the virt-tls pattern — guest speaks plain http:// over synthetic TCP to <real-host>.virt-http.alt, the shim terminates the HTTP protocol and re-expresses it through primitives every host has (fetch), restoring TLS on the real side. Evaluated there as a replacement for the relay-dialer seam and rejected; recorded here as an option for the features whose URLs never cross the wire. This issue is the marker for that option, not a work order.
The enabling fact
Client-side iroh opens TCP only for HTTP-family protocols: the relay dial (HTTP upgrade → websocket), HTTP CONNECT proxying, net_report HTTPS/captive-portal probes, pkarr relay publishing (reqwest), UPnP control (native-only). Sole exception: hickory's DNS-over-TCP fallback for truncated responses — moot here, since DNS must be shim-synthesized anyway and a shim resolver never truncates. So an HTTP-level terminator covers iroh's entire non-relay TCP surface; nothing uncarryable-in-a-browser lurks below it.
Target features
- pkarr-relay publishing (the virt-http customer): stock
PkarrPublisher HTTP(S) PUTs through the shim → components become discoverable via n0's DNS infrastructure. The pkarr relay URL is local config, never published to peers and never received from them, so the scheme-downgrade + suffix fiction is invisible to the wire. This is the missing outbound half of stock discovery.
- DNS discovery resolution (probably not virt-http): hickory's DoH does its own TLS in-guest — blocked for the same reason as everything TLS-in-guest ("never crypto, never key-material synthesis"), and plain-HTTP DoH isn't a thing hickory speaks. The cheaper path is a shim DNS server over synthetic UDP (
Builder::dns_resolver + DnsResolver::with_nameserver at a synthetic addr) — datagram-shaped, fits the existing wake pattern, no TCP machinery. Listed here because it completes the discovery story, not because it needs virt-http.
The boundary (recorded from the #25 analysis)
Not the relay leg. RelayMap URLs are protocol-visible in both directions — outbound in signed discovery records and tickets (a host cannot rewrite signed content), inbound in peers' EndpointAddrs with no rewrite seam (discovery-resolved addresses feed the endpoint internally). Every virtualized URL needs the scheme downgrade (wss→ws, https→http) plus the suffix, so relay-URL fiction breaks interop with stock peers in both directions. The relay connection keeps its seam below the URL layer (lann/iroh#2). Corollary: net_report probes share RelayMap URLs, so probe-latency realism does not come along — the probe gate (lann/iroh#3) stands.
What the shim would own
- Synthetic TCP: wasi:sockets stream sockets + wasi:io streams with backpressure, Node and browser shims — the wake pattern is datagram-only today, and tokio
TcpStream on wasm32-wasip2 under jco is unproven.
- HTTP/1.1 termination: request parse, response synthesis over fetch. Websocket termination (RFC 6455, client-frame unmasking, SHA-1 accept) only if a ws variant is ever wanted — pkarr needs plain request/response, so a first cut skips websockets entirely.
.alt name resolution (shim ip-name-lookup or the synthetic DNS server above).
Open questions
- reqwest's default resolver is GaiResolver — getaddrinfo inside
spawn_blocking, which panics on wasi. Whether std/ip-name-lookup routes around it, or a custom resolver must be plumbed, decides whether "zero iroh patch" actually holds: iroh constructs its pkarr reqwest client internally, so resolver plumbing may need a small upstream config PR after all.
- Loss of streaming/backpressure fidelity through fetch for large bodies (pkarr payloads are tiny; irrelevant until some other consumer appears).
Relation
Gate
Spike-sized validation before any design: (1) tokio TcpStream over shim TCP on wasip2/jco at all; (2) a reqwest GET through it (answers the resolver question empirically); (3) stock PkarrPublisher against a local pkarr relay through the shim. Only then decide scope (component-iroh feature vs. a #26 sibling).
Emerging from the de-vendoring review on #25 (the lann/iroh#2 discussion): the virt-tls pattern — guest speaks plain
http://over synthetic TCP to<real-host>.virt-http.alt, the shim terminates the HTTP protocol and re-expresses it through primitives every host has (fetch), restoring TLS on the real side. Evaluated there as a replacement for the relay-dialer seam and rejected; recorded here as an option for the features whose URLs never cross the wire. This issue is the marker for that option, not a work order.The enabling fact
Client-side iroh opens TCP only for HTTP-family protocols: the relay dial (HTTP upgrade → websocket), HTTP CONNECT proxying, net_report HTTPS/captive-portal probes, pkarr relay publishing (reqwest), UPnP control (native-only). Sole exception: hickory's DNS-over-TCP fallback for truncated responses — moot here, since DNS must be shim-synthesized anyway and a shim resolver never truncates. So an HTTP-level terminator covers iroh's entire non-relay TCP surface; nothing uncarryable-in-a-browser lurks below it.
Target features
PkarrPublisherHTTP(S) PUTs through the shim → components become discoverable via n0's DNS infrastructure. The pkarr relay URL is local config, never published to peers and never received from them, so the scheme-downgrade + suffix fiction is invisible to the wire. This is the missing outbound half of stock discovery.Builder::dns_resolver+DnsResolver::with_nameserverat a synthetic addr) — datagram-shaped, fits the existing wake pattern, no TCP machinery. Listed here because it completes the discovery story, not because it needs virt-http.The boundary (recorded from the #25 analysis)
Not the relay leg. RelayMap URLs are protocol-visible in both directions — outbound in signed discovery records and tickets (a host cannot rewrite signed content), inbound in peers'
EndpointAddrs with no rewrite seam (discovery-resolved addresses feed the endpoint internally). Every virtualized URL needs the scheme downgrade (wss→ws,https→http) plus the suffix, so relay-URL fiction breaks interop with stock peers in both directions. The relay connection keeps its seam below the URL layer (lann/iroh#2). Corollary: net_report probes share RelayMap URLs, so probe-latency realism does not come along — the probe gate (lann/iroh#3) stands.What the shim would own
TcpStreamon wasm32-wasip2 under jco is unproven..altname resolution (shim ip-name-lookup or the synthetic DNS server above).Open questions
spawn_blocking, which panics on wasi. Whether std/ip-name-lookup routes around it, or a custom resolver must be plumbed, decides whether "zero iroh patch" actually holds: iroh constructs its pkarr reqwest client internally, so resolver plumbing may need a small upstream config PR after all.Relation
Gate
Spike-sized validation before any design: (1) tokio TcpStream over shim TCP on wasip2/jco at all; (2) a reqwest GET through it (answers the resolver question empirically); (3) stock
PkarrPublisheragainst a local pkarr relay through the shim. Only then decide scope (component-iroh feature vs. a #26 sibling).