net: support IPv6 in the host netdev and TCP/UDP plumbing

Make the net package address-family aware instead of IPv4-only: DialTCP,
listenTCP and DialUDP now choose AF_INET or AF_INET6 from the target address
(socketFamily), the "only ipv4 supported" guard is replaced by a 4-or-16 byte
check, and "tcp6"/"udp6" network names are accepted.

In the host netdev, sockaddrFromParts builds a SockaddrInet6 for IPv6 addresses
(SockaddrInet4 otherwise), Accept decodes both families, GetHostByName and the
/etc/hosts lookup accept IPv6, and the stub resolver now queries AAAA after A.
Name resolution still prefers IPv4, so the "4"/"6" suffix is advisory for host
names; this is documented on Dial/Listen. Link-local IPv6 zones are not mapped
to a scope id.

Verified on linux/amd64 with tinygo: IPv6 loopback Listen/Accept/Dial over
[::1], AAAA fallback for an IPv6-only host name, and IPv4 behaviour unchanged.
This commit is contained in:
Moses Narrow
2026-06-23 18:19:40 -05:00
committed by Ron Evans
parent 7bf471a0a9
commit 2be2e34090
5 changed files with 105 additions and 53 deletions
+9 -6
View File
@@ -101,8 +101,11 @@ type Dialer struct {
// See Go "net" package Dial() for more information.
//
// Note: Tinygo Dial supports a subset of networks supported by Go Dial,
// specifically: "tcp", "tcp4", "udp", and "udp4". IP and unix networks are
// not supported.
// specifically: "tcp", "tcp4", "tcp6", "udp", "udp4", and "udp6". IP and unix
// networks are not supported. IPv6 addresses are supported, but when dialing a
// host name the resolver prefers an IPv4 (A) address and only falls back to
// IPv6 (AAAA), so the "4"/"6" suffix does not force the address family for name
// resolution.
func Dial(network, address string) (Conn, error) {
var d Dialer
return d.Dial(network, address)
@@ -157,13 +160,13 @@ func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn
// TINYGO: Ignoring context
switch network {
case "tcp", "tcp4":
case "tcp", "tcp4", "tcp6":
raddr, err := ResolveTCPAddr(network, address)
if err != nil {
return nil, err
}
return DialTCP(network, nil, raddr)
case "udp", "udp4":
case "udp", "udp4", "udp6":
raddr, err := ResolveUDPAddr(network, address)
if err != nil {
return nil, err
@@ -271,12 +274,12 @@ func parseNetwork(ctx context.Context, network string, needsProto bool) (afnet s
// See Go "net" package Listen() for more information.
//
// Note: Tinygo Listen supports a subset of networks supported by Go Listen,
// specifically: "tcp", "tcp4". "tcp6" and unix networks are not supported.
// specifically: "tcp", "tcp4", and "tcp6". unix networks are not supported.
func Listen(network, address string) (Listener, error) {
// println("Listen", address)
switch network {
case "tcp", "tcp4":
case "tcp", "tcp4", "tcp6":
default:
return nil, fmt.Errorf("Network %s not supported", network)
}