fix(tsconnect/wasm): Node.js compatibility — safesocket unique name, listen addr normalisation #13

Merged
codinget merged 3 commits from wasm-node-fixes into webnet 2026-06-15 00:17:31 +02:00
2 changed files with 19 additions and 3 deletions
+9
View File
@@ -637,8 +637,12 @@ func (i *jsIPN) logout() {
func (i *jsIPN) shutdown() js.Value { func (i *jsIPN) shutdown() js.Value {
return makePromise(func() (any, error) { return makePromise(func() (any, error) {
i.shutdownOnce.Do(func() { i.shutdownOnce.Do(func() {
if i.lb != nil {
i.lb.Shutdown() i.lb.Shutdown()
}
if i.ln != nil {
i.ln.Close() i.ln.Close()
}
close(i.shutdownCh) close(i.shutdownCh)
}) })
return nil, nil return nil, nil
@@ -873,6 +877,11 @@ func (i *jsIPN) listen(network, addr string) js.Value {
if n == "tcp" { if n == "tcp" {
n = "tcp4" n = "tcp4"
} }
// netstack.ListenTCP requires a full host:port; normalise the
// standard net.Listen form ":port" that omits the host.
if strings.HasPrefix(addr, ":") {
addr = "0.0.0.0" + addr
}
ln, err := i.ns.ListenTCP(n, addr) ln, err := i.ns.ListenTCP(n, addr)
if err != nil { if err != nil {
return nil, err return nil, err
+8 -1
View File
@@ -5,15 +5,22 @@ package safesocket
import ( import (
"context" "context"
"fmt"
"net" "net"
"sync/atomic"
"github.com/akutz/memconn" "github.com/akutz/memconn"
) )
const memName = "Tailscale-IPN" const memName = "Tailscale-IPN"
// memSeq ensures each IPN instance in the same WASM process gets a distinct
// memconn address, so concurrent instances do not conflict on the registry.
var memSeq atomic.Int64
func listen(path string) (net.Listener, error) { func listen(path string) (net.Listener, error) {
return memconn.Listen("memu", memName) name := fmt.Sprintf("%s-%d", memName, memSeq.Add(1))
return memconn.Listen("memu", name)
} }
func connect(ctx context.Context, _ string) (net.Conn, error) { func connect(ctx context.Context, _ string) (net.Conn, error) {