Skip to content

Option: virt-http egress shim (.alt-suffix TCP termination) for stock pkarr publishing and DNS discovery #27

Description

@lann

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 (wssws, httpshttp) 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions