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
152 lines
5.2 KiB
Go
152 lines
5.2 KiB
Go
// TINYGO: The following is copied and modified from Go 1.26.2 official implementation.
|
|
|
|
// Copyright 2012 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.
|
|
|
|
package net
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/netip"
|
|
)
|
|
|
|
// A Resolver looks up names and numbers.
|
|
//
|
|
// A nil *Resolver is equivalent to a zero Resolver.
|
|
//
|
|
// TINYGO: name resolution is backed by the netdev GetHostByName hook;
|
|
// the PreferGo/StrictErrors/Dial fields exist for API compatibility with
|
|
// upstream Go and are ignored.
|
|
type Resolver struct {
|
|
// PreferGo controls whether Go's built-in DNS resolver is preferred
|
|
// on platforms where it's available. It is equivalent to setting
|
|
// GODEBUG=netdns=go, but scoped to just this resolver.
|
|
PreferGo bool
|
|
|
|
// StrictErrors controls the behavior of temporary errors
|
|
// (including timeout, socket errors, and SERVFAIL) when using
|
|
// Go's built-in resolver.
|
|
StrictErrors bool
|
|
|
|
// Dial optionally specifies an alternate dialer for use by
|
|
// Go's built-in DNS resolver to make TCP and UDP connections
|
|
// to DNS services.
|
|
Dial func(ctx context.Context, network, address string) (Conn, error)
|
|
}
|
|
|
|
// DefaultResolver is the resolver used by the package-level Lookup
|
|
// functions and by Dialers without a specified Resolver.
|
|
var DefaultResolver = &Resolver{}
|
|
|
|
// LookupHost looks up the given host using the local resolver.
|
|
// It returns a slice of that host's addresses.
|
|
//
|
|
// LookupHost uses [context.Background] internally; to specify the context, use
|
|
// [Resolver.LookupHost].
|
|
func LookupHost(host string) (addrs []string, err error) {
|
|
return DefaultResolver.LookupHost(context.Background(), host)
|
|
}
|
|
|
|
// LookupHost looks up the given host using the local resolver.
|
|
// It returns a slice of that host's addresses.
|
|
//
|
|
// TINYGO: resolves via netdev.GetHostByName, returning at most one address.
|
|
func (r *Resolver) LookupHost(ctx context.Context, host string) (addrs []string, err error) {
|
|
if host == "" {
|
|
return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
|
|
}
|
|
ip, err := netdev.GetHostByName(host)
|
|
if err != nil {
|
|
return nil, &DNSError{Err: err.Error(), Name: host}
|
|
}
|
|
return []string{ip.String()}, nil
|
|
}
|
|
|
|
// LookupIP looks up host using the local resolver.
|
|
// It returns a slice of that host's IPv4 and IPv6 addresses.
|
|
func LookupIP(host string) ([]IP, error) {
|
|
addrs, err := DefaultResolver.LookupIPAddr(context.Background(), host)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ips := make([]IP, 0, len(addrs))
|
|
for _, addr := range addrs {
|
|
ips = append(ips, addr.IP)
|
|
}
|
|
return ips, nil
|
|
}
|
|
|
|
// LookupIPAddr looks up host using the local resolver.
|
|
// It returns a slice of that host's IPv4 and IPv6 addresses.
|
|
//
|
|
// TINYGO: resolves via netdev.GetHostByName, returning at most one address.
|
|
func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, error) {
|
|
if host == "" {
|
|
return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
|
|
}
|
|
ip, err := netdev.GetHostByName(host)
|
|
if err != nil {
|
|
return nil, &DNSError{Err: err.Error(), Name: host}
|
|
}
|
|
return []IPAddr{{IP: ip.AsSlice(), Zone: ip.Zone()}}, nil
|
|
}
|
|
|
|
// LookupNetIP looks up host using the local resolver.
|
|
// It returns a slice of that host's IP addresses of the type specified by
|
|
// network. The network must be one of "ip", "ip4" or "ip6".
|
|
//
|
|
// TINYGO: resolves via netdev.GetHostByName, returning at most one address.
|
|
func (r *Resolver) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error) {
|
|
if host == "" {
|
|
return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
|
|
}
|
|
ip, err := netdev.GetHostByName(host)
|
|
if err != nil {
|
|
return nil, &DNSError{Err: err.Error(), Name: host}
|
|
}
|
|
return []netip.Addr{ip}, nil
|
|
}
|
|
|
|
// LookupPort looks up the port for the given network and service.
|
|
//
|
|
// LookupPort uses [context.Background] internally; to specify the context, use
|
|
// [Resolver.LookupPort].
|
|
func LookupPort(network, service string) (port int, err error) {
|
|
return DefaultResolver.LookupPort(context.Background(), network, service)
|
|
}
|
|
|
|
// LookupPort looks up the port for the given network and service.
|
|
//
|
|
// TINYGO: not implemented; netdev provides no service database.
|
|
func (r *Resolver) LookupPort(ctx context.Context, network, service string) (port int, err error) {
|
|
return 0, errors.New("net:LookupPort not implemented")
|
|
}
|
|
|
|
// An SRV represents a single DNS SRV record.
|
|
type SRV struct {
|
|
Target string
|
|
Port uint16
|
|
Priority uint16
|
|
Weight uint16
|
|
}
|
|
|
|
// LookupSRV tries to resolve an SRV query of the given service, protocol, and
|
|
// domain name.
|
|
//
|
|
// TINYGO: not implemented; netdev provides no SRV record lookup.
|
|
func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
|
|
return "", nil, errors.New("net:LookupSRV not implemented")
|
|
}
|
|
|
|
// LookupTXT returns the DNS TXT records for the given domain name.
|
|
//
|
|
// TINYGO: not implemented; netdev provides no TXT record lookup.
|
|
func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error) {
|
|
return nil, errors.New("net:LookupTXT not implemented")
|
|
}
|
|
|
|
// errNoSuchHost is returned when the host lookup finds no matching records.
|
|
var errNoSuchHost = errors.New("no such host")
|