net: support IPv6 in the host netdev and TCP/UDP plumbing - #60
Conversation
On the native linux target the net package defaulted to a NOP netdev that returns "Netdev not set" for every operation, so net.Dial/Listen, DNS and anything built on them (net/http, tls) failed at runtime. Native linux does not override the syscall package, and the TinyGo compiler lowers syscall.Syscall/RawSyscall into real system calls, so the standard library socket functions work directly (musl's omitted network module is not needed). Register a default netdev implementing the netdever interface on top of syscall.Socket/Connect/Bind/Listen/Accept/Send/Recv/SetSockOpt, plus a small UDP DNS resolver (/etc/hosts, /etc/resolv.conf) for GetHostByName. Also restore the net.DNSError type used by resolution errors. Blocking sockets under the threads scheduler; IPv4 only. This avoids the internal/poll netpoller dependency that blocked the upstream-net approach. Refs tinygo-org#28
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.
e1d3688 to
11a72b4
Compare
|
Conflicts resolved, and the duplication you saw is explained: this branch is stacked on #59, so GitHub diffs it against It is now rebased onto the freshly-rebased #59, so the IPv6 delta is a single commit touching Of the two options you offered I have taken the second — leave this until #59 is merged — on the grounds that #59 is the larger and more contentious change and folding IPv6 into it would make it harder to review, not easier. Once #59 lands this becomes a small standalone diff. Say the word if you would rather have them as one PR and I will squash them together. |
Summary
Makes the TinyGo
netpackage address-family aware so IPv6 works on the nativeLinux host netdev, instead of being hard-coded to IPv4.
What changes
Shared
netplumbing:DialTCP,listenTCP, andDialUDPchooseAF_INET/AF_INET6from the targetaddress via a new
socketFamily()helper instead of always usingAF_INET."only ipv4 supported"guard inDialTCPbecomes a 4-or-16-byte lengthcheck;
DialUDPgets the same guard."tcp6"/"udp6"network names are accepted.Host netdev (
netdev_native.go):sockaddrFromPartsbuilds asyscall.SockaddrInet6for IPv6 addresses(
SockaddrInet4otherwise, with the zero address as the0.0.0.0wildcard).Acceptdecodes bothSockaddrInet4andSockaddrInet6.GetHostByNameand the/etc/hostslookup accept IPv6 addresses; the stubUDP resolver now queries
AAAAafterA.Behaviour / scope
/etc/hostslookup prefers a v4 match. Because the
netdever.GetHostByNameinterface has nofamily argument, the
"4"/"6"network suffix is advisory for host names — thisis documented on
Dial/Listen. Dialing a literal IPv6 address always uses IPv6.%zone) are not resolved to a scope id.Verification
Built and run with
tinygoonlinux/amd64:net.Listen("tcp", "[::1]:…")+Accept+net.Dialround-trips,RemoteAddr()reports the[::1]peer.net.ResolveTCPAddr("tcp", "ipv6.google.com:80")returns an IPv6 (AAAA) address(A-then-AAAA fallback), while a dual-stack host (
example.com) still resolves toIPv4.
http.Get) unchanged.