@@ -9,6 +9,7 @@ package net
9
9
import (
10
10
"errors"
11
11
"internal/testenv"
12
+ "net/netip"
12
13
"os"
13
14
"reflect"
14
15
"runtime"
@@ -622,3 +623,47 @@ func TestUDPIPVersionReadMsg(t *testing.T) {
622
623
t .Error ("returned UDPAddr is not IPv4" )
623
624
}
624
625
}
626
+
627
+ // TestIPv6WriteMsgUDPAddrPortTargetAddrIPVersion verifies that
628
+ // WriteMsgUDPAddrPort accepts IPv4, IPv4-mapped IPv6, and IPv6 target addresses
629
+ // on a UDPConn listening on "::".
630
+ func TestIPv6WriteMsgUDPAddrPortTargetAddrIPVersion (t * testing.T ) {
631
+ if ! supportsIPv6 () {
632
+ t .Skip ("IPv6 is not supported" )
633
+ }
634
+
635
+ switch runtime .GOOS {
636
+ case "dragonfly" , "openbsd" :
637
+ // DragonflyBSD's IPv6 sockets are always IPv6-only, according to the man page:
638
+ // https://www.dragonflybsd.org/cgi/web-man?command=ip6 (search for IPV6_V6ONLY).
639
+ // OpenBSD's IPv6 sockets are always IPv6-only, according to the man page:
640
+ // https://man.openbsd.org/ip6#IPV6_V6ONLY
641
+ t .Skipf ("skipping on %v" , runtime .GOOS )
642
+ }
643
+
644
+ conn , err := ListenUDP ("udp" , nil )
645
+ if err != nil {
646
+ t .Fatal (err )
647
+ }
648
+ defer conn .Close ()
649
+
650
+ daddr4 := netip .AddrPortFrom (netip .MustParseAddr ("127.0.0.1" ), 12345 )
651
+ daddr4in6 := netip .AddrPortFrom (netip .MustParseAddr ("::ffff:127.0.0.1" ), 12345 )
652
+ daddr6 := netip .AddrPortFrom (netip .MustParseAddr ("::1" ), 12345 )
653
+ buf := make ([]byte , 8 )
654
+
655
+ _ , _ , err = conn .WriteMsgUDPAddrPort (buf , nil , daddr4 )
656
+ if err != nil {
657
+ t .Fatal (err )
658
+ }
659
+
660
+ _ , _ , err = conn .WriteMsgUDPAddrPort (buf , nil , daddr4in6 )
661
+ if err != nil {
662
+ t .Fatal (err )
663
+ }
664
+
665
+ _ , _ , err = conn .WriteMsgUDPAddrPort (buf , nil , daddr6 )
666
+ if err != nil {
667
+ t .Fatal (err )
668
+ }
669
+ }
0 commit comments