Files
net/tlssock.go
Pat Whittingslow d5da3ddeef net: add UDP listen, resolver, DNSError, and TCP listener APIs for wasm (#63)
* net: add UDP listen, resolver, DNSError, and TCP listener APIs for wasm

TinyGo's net package was missing several symbols that upstream Go's
js/wasm net declares, blocking builds that pull pion/transport, pion/dtls,
and similar (via netbird's WASM client). Add them, backed by the existing
netdev abstraction so they compile for all targets and no-op cleanly under
nopNetdev (matching Go's js runtime behavior):

- DNSError type (dnserror.go), copied from Go 1.26.2.
- Resolver + DefaultResolver with LookupHost/LookupIP/LookupIPAddr/
  LookupNetIP/LookupPort; LookupHost/LookupIP package funcs; Dialer.Resolver
  field for API compatibility.
- UDPConn: ListenUDP, ReadFromUDP(AddrPort), WriteToUDP(AddrPort),
  SetReadBuffer, SetWriteBuffer.
- TCPConn: CloseRead, SetNoDelay, SetReadBuffer, SetWriteBuffer,
  ReadFrom(io.Reader).
- TCPListener: ListenTCP, AcceptTCP, SetDeadline; ListenPacket package func.
- Interface: Addrs, MulticastAddrs stubs.

* more complete PR for adding more net support (#64)

* format unixsock
2026-07-06 20:24:35 +02:00

150 lines
3.3 KiB
Go

// TINYGO: The following is copied and modified from Go 1.21.4 official implementation.
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// TLS low level connection and record layer
package net
import (
"context"
"internal/itoa"
"io"
"net/netip"
"strconv"
"time"
)
// TLSAddr represents the address of a TLS end point.
type TLSAddr struct {
Host string
Port int
}
func (a *TLSAddr) Network() string { return "tls" }
func (a *TLSAddr) String() string {
if a == nil {
return "<nil>"
}
return JoinHostPort(a.Host, itoa.Itoa(a.Port))
}
// A TLSConn represents a secured connection.
// It implements the net.Conn interface.
type TLSConn struct {
fd int
net string
laddr *TLSAddr
raddr *TLSAddr
readDeadline time.Time
writeDeadline time.Time
}
func DialTLS(addr string) (*TLSConn, error) {
host, sport, err := SplitHostPort(addr)
if err != nil {
return nil, err
}
port, err := strconv.Atoi(sport)
if err != nil {
return nil, err
}
if port == 0 {
port = 443
}
fd, err := netdev.Socket(_AF_INET, _SOCK_STREAM, _IPPROTO_TLS)
if err != nil {
return nil, err
}
addrport := netip.AddrPortFrom(netip.Addr{}, uint16(port))
if err = netdev.Connect(fd, host, addrport); err != nil {
netdev.Close(fd)
return nil, err
}
return &TLSConn{
fd: fd,
net: "tls",
raddr: &TLSAddr{host, port},
}, nil
}
func (c *TLSConn) Read(b []byte) (int, error) {
n, err := netdev.Recv(c.fd, b, 0, c.readDeadline)
// Turn the -1 socket error into 0 and let err speak for error
if n < 0 {
n = 0
}
if err != nil && err != io.EOF {
err = &OpError{Op: "read", Net: c.net, Source: c.laddr, Addr: c.raddr, Err: err}
}
return n, err
}
func (c *TLSConn) Write(b []byte) (int, error) {
n, err := netdev.Send(c.fd, b, 0, c.writeDeadline)
// Turn the -1 socket error into 0 and let err speak for error
if n < 0 {
n = 0
}
if err != nil {
err = &OpError{Op: "write", Net: c.net, Source: c.laddr, Addr: c.raddr, Err: err}
}
return n, err
}
func (c *TLSConn) Close() error {
return netdev.Close(c.fd)
}
func (c *TLSConn) LocalAddr() Addr {
return c.laddr
}
func (c *TLSConn) RemoteAddr() Addr {
return c.raddr
}
func (c *TLSConn) SetDeadline(t time.Time) error {
c.readDeadline = t
c.writeDeadline = t
return nil
}
func (c *TLSConn) SetReadDeadline(t time.Time) error {
c.readDeadline = t
return nil
}
func (c *TLSConn) SetWriteDeadline(t time.Time) error {
c.writeDeadline = t
return nil
}
// Handshake runs the client or server handshake
// protocol if it has not yet been run.
//
// Most uses of this package need not call Handshake explicitly: the
// first Read or Write will call it automatically.
//
// For control over canceling or setting a timeout on a handshake, use
// HandshakeContext or the Dialer's DialContext method instead.
func (c *TLSConn) Handshake() error {
panic("TLSConn.Handshake() not implemented")
return nil
}
// HandshakeContext runs the client or server handshake protocol if it has not
// yet been run. TINYGO: TLS is offloaded to the network device; this exists to
// satisfy callers (e.g. pion/ice) that require the context-aware variant.
func (c *TLSConn) HandshakeContext(ctx context.Context) error {
return c.Handshake()
}