1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
19 func BenchmarkUDP6LinkLocalUnicast(b
*testing
.B
) {
20 testHookUninstaller
.Do(uninstallTestHooks
)
23 b
.Skip("IPv6 is not supported")
25 ifi
:= loopbackInterface()
27 b
.Skip("loopback interface not found")
29 lla
:= ipv6LinkLocalUnicastAddr(ifi
)
31 b
.Skip("IPv6 link-local unicast address not found")
34 c1
, err
:= ListenPacket("udp6", JoinHostPort(lla
+"%"+ifi
.Name
, "0"))
39 c2
, err
:= ListenPacket("udp6", JoinHostPort(lla
+"%"+ifi
.Name
, "0"))
46 for i
:= 0; i
< b
.N
; i
++ {
47 if _
, err
:= c1
.WriteTo(buf
[:], c2
.LocalAddr()); err
!= nil {
50 if _
, _
, err
:= c2
.ReadFrom(buf
[:]); err
!= nil {
56 type resolveUDPAddrTest
struct {
63 var resolveUDPAddrTests
= []resolveUDPAddrTest
{
64 {"udp", "127.0.0.1:0", &UDPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 0}, nil},
65 {"udp4", "127.0.0.1:65535", &UDPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 65535}, nil},
67 {"udp", "[::1]:0", &UDPAddr
{IP
: ParseIP("::1"), Port
: 0}, nil},
68 {"udp6", "[::1]:65535", &UDPAddr
{IP
: ParseIP("::1"), Port
: 65535}, nil},
70 {"udp", "[::1%en0]:1", &UDPAddr
{IP
: ParseIP("::1"), Port
: 1, Zone
: "en0"}, nil},
71 {"udp6", "[::1%911]:2", &UDPAddr
{IP
: ParseIP("::1"), Port
: 2, Zone
: "911"}, nil},
73 {"", "127.0.0.1:0", &UDPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 0}, nil}, // Go 1.0 behavior
74 {"", "[::1]:0", &UDPAddr
{IP
: ParseIP("::1"), Port
: 0}, nil}, // Go 1.0 behavior
76 {"udp", ":12345", &UDPAddr
{Port
: 12345}, nil},
78 {"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
80 {"udp", "127.0.0.1:domain", &UDPAddr
{IP
: ParseIP("127.0.0.1"), Port
: 53}, nil},
81 {"udp", "[::ffff:127.0.0.1]:domain", &UDPAddr
{IP
: ParseIP("::ffff:127.0.0.1"), Port
: 53}, nil},
82 {"udp", "[2001:db8::1]:domain", &UDPAddr
{IP
: ParseIP("2001:db8::1"), Port
: 53}, nil},
83 {"udp4", "127.0.0.1:domain", &UDPAddr
{IP
: ParseIP("127.0.0.1"), Port
: 53}, nil},
84 {"udp4", "[::ffff:127.0.0.1]:domain", &UDPAddr
{IP
: ParseIP("127.0.0.1"), Port
: 53}, nil},
85 {"udp6", "[2001:db8::1]:domain", &UDPAddr
{IP
: ParseIP("2001:db8::1"), Port
: 53}, nil},
87 {"udp4", "[2001:db8::1]:domain", nil, &AddrError
{Err
: errNoSuitableAddress
.Error(), Addr
: "2001:db8::1"}},
88 {"udp6", "127.0.0.1:domain", nil, &AddrError
{Err
: errNoSuitableAddress
.Error(), Addr
: "127.0.0.1"}},
89 {"udp6", "[::ffff:127.0.0.1]:domain", nil, &AddrError
{Err
: errNoSuitableAddress
.Error(), Addr
: "::ffff:127.0.0.1"}},
92 func TestResolveUDPAddr(t
*testing
.T
) {
93 origTestHookLookupIP
:= testHookLookupIP
94 defer func() { testHookLookupIP
= origTestHookLookupIP
}()
95 testHookLookupIP
= lookupLocalhost
97 for _
, tt
:= range resolveUDPAddrTests
{
98 addr
, err
:= ResolveUDPAddr(tt
.network
, tt
.litAddrOrName
)
99 if !reflect
.DeepEqual(addr
, tt
.addr
) ||
!reflect
.DeepEqual(err
, tt
.err
) {
100 t
.Errorf("ResolveUDPAddr(%q, %q) = %#v, %v, want %#v, %v", tt
.network
, tt
.litAddrOrName
, addr
, err
, tt
.addr
, tt
.err
)
104 addr2
, err
:= ResolveUDPAddr(addr
.Network(), addr
.String())
105 if !reflect
.DeepEqual(addr2
, tt
.addr
) || err
!= tt
.err
{
106 t
.Errorf("(%q, %q): ResolveUDPAddr(%q, %q) = %#v, %v, want %#v, %v", tt
.network
, tt
.litAddrOrName
, addr
.Network(), addr
.String(), addr2
, err
, tt
.addr
, tt
.err
)
112 func TestWriteToUDP(t
*testing
.T
) {
113 switch runtime
.GOOS
{
115 t
.Skipf("not supported on %s", runtime
.GOOS
)
118 c
, err
:= ListenPacket("udp", "127.0.0.1:0")
124 testWriteToConn(t
, c
.LocalAddr().String())
125 testWriteToPacketConn(t
, c
.LocalAddr().String())
128 func testWriteToConn(t
*testing
.T
, raddr
string) {
129 c
, err
:= Dial("udp", raddr
)
135 ra
, err
:= ResolveUDPAddr("udp", raddr
)
140 b
:= []byte("CONNECTED-MODE SOCKET")
141 _
, err
= c
.(*UDPConn
).WriteToUDP(b
, ra
)
143 t
.Fatal("should fail")
145 if err
!= nil && err
.(*OpError
).Err
!= ErrWriteToConnected
{
146 t
.Fatalf("should fail as ErrWriteToConnected: %v", err
)
148 _
, err
= c
.(*UDPConn
).WriteTo(b
, ra
)
150 t
.Fatal("should fail")
152 if err
!= nil && err
.(*OpError
).Err
!= ErrWriteToConnected
{
153 t
.Fatalf("should fail as ErrWriteToConnected: %v", err
)
159 _
, _
, err
= c
.(*UDPConn
).WriteMsgUDP(b
, nil, ra
)
161 t
.Fatal("should fail")
163 if err
!= nil && err
.(*OpError
).Err
!= ErrWriteToConnected
{
164 t
.Fatalf("should fail as ErrWriteToConnected: %v", err
)
166 _
, _
, err
= c
.(*UDPConn
).WriteMsgUDP(b
, nil, nil)
172 func testWriteToPacketConn(t
*testing
.T
, raddr
string) {
173 c
, err
:= ListenPacket("udp", "127.0.0.1:0")
179 ra
, err
:= ResolveUDPAddr("udp", raddr
)
184 b
:= []byte("UNCONNECTED-MODE SOCKET")
185 _
, err
= c
.(*UDPConn
).WriteToUDP(b
, ra
)
189 _
, err
= c
.WriteTo(b
, ra
)
193 _
, err
= c
.(*UDPConn
).Write(b
)
195 t
.Fatal("should fail")
197 _
, _
, err
= c
.(*UDPConn
).WriteMsgUDP(b
, nil, nil)
199 t
.Fatal("should fail")
201 if err
!= nil && err
.(*OpError
).Err
!= errMissingAddress
{
202 t
.Fatalf("should fail as errMissingAddress: %v", err
)
204 _
, _
, err
= c
.(*UDPConn
).WriteMsgUDP(b
, nil, ra
)
210 var udpConnLocalNameTests
= []struct {
214 {"udp4", &UDPAddr
{IP
: IPv4(127, 0, 0, 1)}},
215 {"udp4", &UDPAddr
{}},
219 func TestUDPConnLocalName(t
*testing
.T
) {
220 testenv
.MustHaveExternalNetwork(t
)
222 for _
, tt
:= range udpConnLocalNameTests
{
223 c
, err
:= ListenUDP(tt
.net
, tt
.laddr
)
229 if a
, ok
:= la
.(*UDPAddr
); !ok || a
.Port
== 0 {
230 t
.Fatalf("got %v; expected a proper address with non-zero port number", la
)
235 func TestUDPConnLocalAndRemoteNames(t
*testing
.T
) {
236 for _
, laddr
:= range []string{"", "127.0.0.1:0"} {
237 c1
, err
:= ListenPacket("udp", "127.0.0.1:0")
246 if la
, err
= ResolveUDPAddr("udp", laddr
); err
!= nil {
250 c2
, err
:= DialUDP("udp", la
, c1
.LocalAddr().(*UDPAddr
))
256 var connAddrs
= [4]struct {
260 {c1
.LocalAddr(), true},
261 {c1
.(*UDPConn
).RemoteAddr(), false},
262 {c2
.LocalAddr(), true},
263 {c2
.RemoteAddr(), true},
265 for _
, ca
:= range connAddrs
{
266 if a
, ok
:= ca
.got
.(*UDPAddr
); ok
!= ca
.ok || ok
&& a
.Port
== 0 {
267 t
.Fatalf("got %v; expected a proper address with non-zero port number", ca
.got
)
273 func TestIPv6LinkLocalUnicastUDP(t
*testing
.T
) {
274 testenv
.MustHaveExternalNetwork(t
)
277 t
.Skip("IPv6 is not supported")
280 for i
, tt
:= range ipv6LinkLocalUnicastUDPTests
{
281 c1
, err
:= ListenPacket(tt
.network
, tt
.address
)
283 // It might return "LookupHost returned no
284 // suitable address" error on some platforms.
288 ls
:= (&packetListener
{PacketConn
: c1
}).newLocalServer()
290 ch
:= make(chan error
, 1)
291 handler
:= func(ls
*localPacketServer
, c PacketConn
) { packetTransponder(c
, ch
) }
292 if err
:= ls
.buildup(handler
); err
!= nil {
295 if la
, ok
:= c1
.LocalAddr().(*UDPAddr
); !ok ||
!tt
.nameLookup
&& la
.Zone
== "" {
296 t
.Fatalf("got %v; expected a proper address with zone identifier", la
)
299 c2
, err
:= Dial(tt
.network
, ls
.PacketConn
.LocalAddr().String())
304 if la
, ok
:= c2
.LocalAddr().(*UDPAddr
); !ok ||
!tt
.nameLookup
&& la
.Zone
== "" {
305 t
.Fatalf("got %v; expected a proper address with zone identifier", la
)
307 if ra
, ok
:= c2
.RemoteAddr().(*UDPAddr
); !ok ||
!tt
.nameLookup
&& ra
.Zone
== "" {
308 t
.Fatalf("got %v; expected a proper address with zone identifier", ra
)
311 if _
, err
:= c2
.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err
!= nil {
314 b
:= make([]byte, 32)
315 if _
, err
:= c2
.Read(b
); err
!= nil {
319 for err
:= range ch
{
320 t
.Errorf("#%d: %v", i
, err
)
325 func TestUDPZeroBytePayload(t
*testing
.T
) {
326 switch runtime
.GOOS
{
328 t
.Skipf("not supported on %s", runtime
.GOOS
)
329 case "darwin", "ios":
330 testenv
.SkipFlaky(t
, 29225)
333 c
:= newLocalPacketListener(t
, "udp")
336 for _
, genericRead
:= range []bool{false, true} {
337 n
, err
:= c
.WriteTo(nil, c
.LocalAddr())
342 t
.Errorf("got %d; want 0", n
)
344 c
.SetReadDeadline(time
.Now().Add(30 * time
.Second
))
348 _
, err
= c
.(Conn
).Read(b
[:])
351 _
, _
, err
= c
.ReadFrom(b
[:])
355 t
.Errorf("%s of zero byte packet failed: %v", name
, err
)
360 func TestUDPZeroByteBuffer(t
*testing
.T
) {
361 switch runtime
.GOOS
{
363 t
.Skipf("not supported on %s", runtime
.GOOS
)
366 c
:= newLocalPacketListener(t
, "udp")
369 b
:= []byte("UDP ZERO BYTE BUFFER TEST")
370 for _
, genericRead
:= range []bool{false, true} {
371 n
, err
:= c
.WriteTo(b
, c
.LocalAddr())
376 t
.Errorf("got %d; want %d", n
, len(b
))
378 c
.SetReadDeadline(time
.Now().Add(100 * time
.Millisecond
))
380 _
, err
= c
.(Conn
).Read(nil)
382 _
, _
, err
= c
.ReadFrom(nil)
385 case nil: // ReadFrom succeeds
386 default: // Read may timeout, it depends on the platform
387 if nerr
, ok
:= err
.(Error
); (!ok ||
!nerr
.Timeout()) && runtime
.GOOS
!= "windows" { // Windows returns WSAEMSGSIZE
394 func TestUDPReadSizeError(t
*testing
.T
) {
395 switch runtime
.GOOS
{
397 t
.Skipf("not supported on %s", runtime
.GOOS
)
400 c1
:= newLocalPacketListener(t
, "udp")
403 c2
, err
:= Dial("udp", c1
.LocalAddr().String())
409 b1
:= []byte("READ SIZE ERROR TEST")
410 for _
, genericRead
:= range []bool{false, true} {
411 n
, err
:= c2
.Write(b1
)
416 t
.Errorf("got %d; want %d", n
, len(b1
))
418 b2
:= make([]byte, len(b1
)-1)
420 n
, err
= c1
.(Conn
).Read(b2
)
422 n
, _
, err
= c1
.ReadFrom(b2
)
424 if err
!= nil && runtime
.GOOS
!= "windows" { // Windows returns WSAEMSGSIZE
428 t
.Fatalf("got %d; want %d", n
, len(b1
)-1)
433 // TestUDPReadTimeout verifies that ReadFromUDP with timeout returns an error
434 // without data or an address.
435 func TestUDPReadTimeout(t
*testing
.T
) {
436 la
, err
:= ResolveUDPAddr("udp4", "127.0.0.1:0")
440 c
, err
:= ListenUDP("udp4", la
)
446 c
.SetDeadline(time
.Now())
448 n
, addr
, err
:= c
.ReadFromUDP(b
)
449 if !errors
.Is(err
, os
.ErrDeadlineExceeded
) {
450 t
.Errorf("ReadFromUDP got err %v want os.ErrDeadlineExceeded", err
)
453 t
.Errorf("ReadFromUDP got n %d want 0", n
)
456 t
.Errorf("ReadFromUDP got addr %+#v want nil", addr
)
460 func TestAllocs(t
*testing
.T
) {
461 switch runtime
.GOOS
{
463 // Plan9 wasn't optimized.
464 t
.Skipf("skipping on %v", runtime
.GOOS
)
466 builder
:= os
.Getenv("GO_BUILDER_NAME")
468 case "linux-amd64-noopt":
469 // Optimizations are required to remove the allocs.
470 t
.Skipf("skipping on %v", builder
)
472 conn
, err
:= ListenUDP("udp4", &UDPAddr
{IP
: IPv4(127, 0, 0, 1)})
477 addr
:= conn
.LocalAddr()
478 addrPort
:= addr
.(*UDPAddr
).AddrPort()
479 buf
:= make([]byte, 8)
481 allocs
:= testing
.AllocsPerRun(1000, func() {
482 _
, _
, err
:= conn
.WriteMsgUDPAddrPort(buf
, nil, addrPort
)
486 _
, _
, _
, _
, err
= conn
.ReadMsgUDPAddrPort(buf
, nil)
491 if got
:= int(allocs
); got
!= 0 {
492 t
.Errorf("WriteMsgUDPAddrPort/ReadMsgUDPAddrPort allocated %d objects", got
)
495 allocs
= testing
.AllocsPerRun(1000, func() {
496 _
, err
:= conn
.WriteToUDPAddrPort(buf
, addrPort
)
500 _
, _
, err
= conn
.ReadFromUDPAddrPort(buf
)
505 if got
:= int(allocs
); got
!= 0 {
506 t
.Errorf("WriteToUDPAddrPort/ReadFromUDPAddrPort allocated %d objects", got
)
509 allocs
= testing
.AllocsPerRun(1000, func() {
510 _
, err
:= conn
.WriteTo(buf
, addr
)
514 _
, _
, err
= conn
.ReadFromUDP(buf
)
519 if got
:= int(allocs
); got
!= 1 {
520 if runtime
.Compiler
!= "gccgo" {
521 t
.Errorf("WriteTo/ReadFromUDP allocated %d objects", got
)
526 func BenchmarkReadWriteMsgUDPAddrPort(b
*testing
.B
) {
527 conn
, err
:= ListenUDP("udp4", &UDPAddr
{IP
: IPv4(127, 0, 0, 1)})
532 addr
:= conn
.LocalAddr().(*UDPAddr
).AddrPort()
533 buf
:= make([]byte, 8)
536 for i
:= 0; i
< b
.N
; i
++ {
537 _
, _
, err
:= conn
.WriteMsgUDPAddrPort(buf
, nil, addr
)
541 _
, _
, _
, _
, err
= conn
.ReadMsgUDPAddrPort(buf
, nil)
548 func BenchmarkWriteToReadFromUDP(b
*testing
.B
) {
549 conn
, err
:= ListenUDP("udp4", &UDPAddr
{IP
: IPv4(127, 0, 0, 1)})
554 addr
:= conn
.LocalAddr()
555 buf
:= make([]byte, 8)
558 for i
:= 0; i
< b
.N
; i
++ {
559 _
, err
:= conn
.WriteTo(buf
, addr
)
563 _
, _
, err
= conn
.ReadFromUDP(buf
)
570 func BenchmarkWriteToReadFromUDPAddrPort(b
*testing
.B
) {
571 conn
, err
:= ListenUDP("udp4", &UDPAddr
{IP
: IPv4(127, 0, 0, 1)})
576 addr
:= conn
.LocalAddr().(*UDPAddr
).AddrPort()
577 buf
:= make([]byte, 8)
580 for i
:= 0; i
< b
.N
; i
++ {
581 _
, err
:= conn
.WriteToUDPAddrPort(buf
, addr
)
585 _
, _
, err
= conn
.ReadFromUDPAddrPort(buf
)
592 func TestUDPIPVersionReadMsg(t
*testing
.T
) {
593 switch runtime
.GOOS
{
595 t
.Skipf("skipping on %v", runtime
.GOOS
)
597 conn
, err
:= ListenUDP("udp4", &UDPAddr
{IP
: IPv4(127, 0, 0, 1)})
602 daddr
:= conn
.LocalAddr().(*UDPAddr
).AddrPort()
603 buf
:= make([]byte, 8)
604 _
, err
= conn
.WriteToUDPAddrPort(buf
, daddr
)
608 _
, _
, _
, saddr
, err
:= conn
.ReadMsgUDPAddrPort(buf
, nil)
612 if !saddr
.Addr().Is4() {
613 t
.Error("returned AddrPort is not IPv4")
615 _
, err
= conn
.WriteToUDPAddrPort(buf
, daddr
)
619 _
, _
, _
, soldaddr
, err
:= conn
.ReadMsgUDP(buf
, nil)
623 if len(soldaddr
.IP
) != 4 {
624 t
.Error("returned UDPAddr is not IPv4")