Commit Graph
2 Commits
Author SHA1 Message Date
codinget dec5041157 feat(tsconnect): expose dialTLS to JS
Add ipn.dialTLS(addr, opts?) which dials a TCP connection through
the Tailscale dialer and performs a TLS handshake on top, returning
a JS Conn just like ipn.dial.

WASM has no system root pool, so verification defaults to the
baked-in LetsEncrypt ISRG roots already linked via net/bakedroots.
That covers any tailnet HTTPS endpoint provisioned via
`tailscale cert`. Callers can override with opts.caCerts (PEM) or
bypass entirely with opts.insecureSkipVerify, and override SNI with
opts.serverName.

Marginal binary cost is ~10 KiB on top of the existing ~31.6 MiB
wasm: crypto/tls and the x509 verification path are already pulled
in by control/controlclient and net/tlsdial.
2026-07-28 17:31:13 +00:00
codinget 434acfdf03 feat(tsconnect): expose dial, listen and listenICMP to JS
Wire up the userspace networking primitives to the JS bridge so
browser callers can initiate outbound and receive inbound traffic
over the Tailscale network:

- ipn.dial(network, addr) wraps a tsdial UserDial into a JS Conn
  with read/write/close/localAddr/remoteAddr.
- ipn.listen(network, addr) wraps a netstack ListenPacket into a
  JS PacketConn with readFrom/writeTo/close/localAddr.
- ipn.listenICMP("icmp4"|"icmp6"|"icmp") creates a raw ICMP
  endpoint on the underlying gVisor stack and wraps it as a
  PacketConn for sending/receiving ping traffic.

To support listenICMP, netstack.Impl gains a Stack() accessor that
returns the underlying *stack.Stack so jsIPN can call NewEndpoint
with icmp.ProtocolNumber4/6.

Binary I/O uses js.CopyBytesToGo / js.CopyBytesToJS to move bytes
across the syscall/js boundary without base64 round-trips.
2026-07-28 17:31:13 +00:00