mirror of
https://github.com/tinygo-org/net.git
synced 2026-07-26 08:18:39 +00:00
d5da3ddeef
* 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
150 lines
3.3 KiB
Go
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()
|
|
}
|