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.
15 func BenchmarkUDP6LinkLocalUnicast(b
*testing
.B
) {
16 testHookUninstaller
.Do(uninstallTestHooks
)
19 b
.Skip("IPv6 is not supported")
21 ifi
:= loopbackInterface()
23 b
.Skip("loopback interface not found")
25 lla
:= ipv6LinkLocalUnicastAddr(ifi
)
27 b
.Skip("IPv6 link-local unicast address not found")
30 c1
, err
:= ListenPacket("udp6", JoinHostPort(lla
+"%"+ifi
.Name
, "0"))
35 c2
, err
:= ListenPacket("udp6", JoinHostPort(lla
+"%"+ifi
.Name
, "0"))
42 for i
:= 0; i
< b
.N
; i
++ {
43 if _
, err
:= c1
.WriteTo(buf
[:], c2
.LocalAddr()); err
!= nil {
46 if _
, _
, err
:= c2
.ReadFrom(buf
[:]); err
!= nil {
52 type resolveUDPAddrTest
struct {
59 var resolveUDPAddrTests
= []resolveUDPAddrTest
{
60 {"udp", "127.0.0.1:0", &UDPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 0}, nil},
61 {"udp4", "127.0.0.1:65535", &UDPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 65535}, nil},
63 {"udp", "[::1]:0", &UDPAddr
{IP
: ParseIP("::1"), Port
: 0}, nil},
64 {"udp6", "[::1]:65535", &UDPAddr
{IP
: ParseIP("::1"), Port
: 65535}, nil},
66 {"udp", "[::1%en0]:1", &UDPAddr
{IP
: ParseIP("::1"), Port
: 1, Zone
: "en0"}, nil},
67 {"udp6", "[::1%911]:2", &UDPAddr
{IP
: ParseIP("::1"), Port
: 2, Zone
: "911"}, nil},
69 {"", "127.0.0.1:0", &UDPAddr
{IP
: IPv4(127, 0, 0, 1), Port
: 0}, nil}, // Go 1.0 behavior
70 {"", "[::1]:0", &UDPAddr
{IP
: ParseIP("::1"), Port
: 0}, nil}, // Go 1.0 behavior
72 {"udp", ":12345", &UDPAddr
{Port
: 12345}, nil},
74 {"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
76 {"udp", "127.0.0.1:domain", &UDPAddr
{IP
: ParseIP("127.0.0.1"), Port
: 53}, nil},
77 {"udp", "[::ffff:127.0.0.1]:domain", &UDPAddr
{IP
: ParseIP("::ffff:127.0.0.1"), Port
: 53}, nil},
78 {"udp", "[2001:db8::1]:domain", &UDPAddr
{IP
: ParseIP("2001:db8::1"), Port
: 53}, nil},
79 {"udp4", "127.0.0.1:domain", &UDPAddr
{IP
: ParseIP("127.0.0.1"), Port
: 53}, nil},
80 {"udp4", "[::ffff:127.0.0.1]:domain", &UDPAddr
{IP
: ParseIP("127.0.0.1"), Port
: 53}, nil},
81 {"udp6", "[2001:db8::1]:domain", &UDPAddr
{IP
: ParseIP("2001:db8::1"), Port
: 53}, nil},
83 {"udp4", "[2001:db8::1]:domain", nil, &AddrError
{Err
: errNoSuitableAddress
.Error(), Addr
: "2001:db8::1"}},
84 {"udp6", "127.0.0.1:domain", nil, &AddrError
{Err
: errNoSuitableAddress
.Error(), Addr
: "127.0.0.1"}},
85 {"udp6", "[::ffff:127.0.0.1]:domain", nil, &AddrError
{Err
: errNoSuitableAddress
.Error(), Addr
: "::ffff:127.0.0.1"}},
88 func TestResolveUDPAddr(t
*testing
.T
) {
89 origTestHookLookupIP
:= testHookLookupIP
90 defer func() { testHookLookupIP
= origTestHookLookupIP
}()
91 testHookLookupIP
= lookupLocalhost
93 for _
, tt
:= range resolveUDPAddrTests
{
94 addr
, err
:= ResolveUDPAddr(tt
.network
, tt
.litAddrOrName
)
95 if !reflect
.DeepEqual(addr
, tt
.addr
) ||
!reflect
.DeepEqual(err
, tt
.err
) {
96 t
.Errorf("ResolveUDPAddr(%q, %q) = %#v, %v, want %#v, %v", tt
.network
, tt
.litAddrOrName
, addr
, err
, tt
.addr
, tt
.err
)
100 addr2
, err
:= ResolveUDPAddr(addr
.Network(), addr
.String())
101 if !reflect
.DeepEqual(addr2
, tt
.addr
) || err
!= tt
.err
{
102 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
)
108 func TestWriteToUDP(t
*testing
.T
) {
109 switch runtime
.GOOS
{
111 t
.Skipf("not supported on %s", runtime
.GOOS
)
114 c
, err
:= ListenPacket("udp", "127.0.0.1:0")
120 testWriteToConn(t
, c
.LocalAddr().String())
121 testWriteToPacketConn(t
, c
.LocalAddr().String())
124 func testWriteToConn(t
*testing
.T
, raddr
string) {
125 c
, err
:= Dial("udp", raddr
)
131 ra
, err
:= ResolveUDPAddr("udp", raddr
)
136 b
:= []byte("CONNECTED-MODE SOCKET")
137 _
, err
= c
.(*UDPConn
).WriteToUDP(b
, ra
)
139 t
.Fatal("should fail")
141 if err
!= nil && err
.(*OpError
).Err
!= ErrWriteToConnected
{
142 t
.Fatalf("should fail as ErrWriteToConnected: %v", err
)
144 _
, err
= c
.(*UDPConn
).WriteTo(b
, ra
)
146 t
.Fatal("should fail")
148 if err
!= nil && err
.(*OpError
).Err
!= ErrWriteToConnected
{
149 t
.Fatalf("should fail as ErrWriteToConnected: %v", err
)
155 _
, _
, err
= c
.(*UDPConn
).WriteMsgUDP(b
, nil, ra
)
157 t
.Fatal("should fail")
159 if err
!= nil && err
.(*OpError
).Err
!= ErrWriteToConnected
{
160 t
.Fatalf("should fail as ErrWriteToConnected: %v", err
)
162 _
, _
, err
= c
.(*UDPConn
).WriteMsgUDP(b
, nil, nil)
163 switch runtime
.GOOS
{
164 case "nacl", "windows": // see golang.org/issue/9252
165 t
.Skipf("not implemented yet on %s", runtime
.GOOS
)
173 func testWriteToPacketConn(t
*testing
.T
, raddr
string) {
174 c
, err
:= ListenPacket("udp", "127.0.0.1:0")
180 ra
, err
:= ResolveUDPAddr("udp", raddr
)
185 b
:= []byte("UNCONNECTED-MODE SOCKET")
186 _
, err
= c
.(*UDPConn
).WriteToUDP(b
, ra
)
190 _
, err
= c
.WriteTo(b
, ra
)
194 _
, err
= c
.(*UDPConn
).Write(b
)
196 t
.Fatal("should fail")
198 _
, _
, err
= c
.(*UDPConn
).WriteMsgUDP(b
, nil, nil)
200 t
.Fatal("should fail")
202 if err
!= nil && err
.(*OpError
).Err
!= errMissingAddress
{
203 t
.Fatalf("should fail as errMissingAddress: %v", err
)
205 _
, _
, err
= c
.(*UDPConn
).WriteMsgUDP(b
, nil, ra
)
206 switch runtime
.GOOS
{
207 case "nacl", "windows": // see golang.org/issue/9252
208 t
.Skipf("not implemented yet on %s", runtime
.GOOS
)
216 var udpConnLocalNameTests
= []struct {
220 {"udp4", &UDPAddr
{IP
: IPv4(127, 0, 0, 1)}},
221 {"udp4", &UDPAddr
{}},
225 func TestUDPConnLocalName(t
*testing
.T
) {
226 testenv
.MustHaveExternalNetwork(t
)
228 for _
, tt
:= range udpConnLocalNameTests
{
229 c
, err
:= ListenUDP(tt
.net
, tt
.laddr
)
235 if a
, ok
:= la
.(*UDPAddr
); !ok || a
.Port
== 0 {
236 t
.Fatalf("got %v; expected a proper address with non-zero port number", la
)
241 func TestUDPConnLocalAndRemoteNames(t
*testing
.T
) {
242 for _
, laddr
:= range []string{"", "127.0.0.1:0"} {
243 c1
, err
:= ListenPacket("udp", "127.0.0.1:0")
252 if la
, err
= ResolveUDPAddr("udp", laddr
); err
!= nil {
256 c2
, err
:= DialUDP("udp", la
, c1
.LocalAddr().(*UDPAddr
))
262 var connAddrs
= [4]struct {
266 {c1
.LocalAddr(), true},
267 {c1
.(*UDPConn
).RemoteAddr(), false},
268 {c2
.LocalAddr(), true},
269 {c2
.RemoteAddr(), true},
271 for _
, ca
:= range connAddrs
{
272 if a
, ok
:= ca
.got
.(*UDPAddr
); ok
!= ca
.ok || ok
&& a
.Port
== 0 {
273 t
.Fatalf("got %v; expected a proper address with non-zero port number", ca
.got
)
279 func TestIPv6LinkLocalUnicastUDP(t
*testing
.T
) {
280 testenv
.MustHaveExternalNetwork(t
)
283 t
.Skip("IPv6 is not supported")
286 for i
, tt
:= range ipv6LinkLocalUnicastUDPTests
{
287 c1
, err
:= ListenPacket(tt
.network
, tt
.address
)
289 // It might return "LookupHost returned no
290 // suitable address" error on some platforms.
294 ls
, err
:= (&packetListener
{PacketConn
: c1
}).newLocalServer()
299 ch
:= make(chan error
, 1)
300 handler
:= func(ls
*localPacketServer
, c PacketConn
) { packetTransponder(c
, ch
) }
301 if err
:= ls
.buildup(handler
); err
!= nil {
304 if la
, ok
:= c1
.LocalAddr().(*UDPAddr
); !ok ||
!tt
.nameLookup
&& la
.Zone
== "" {
305 t
.Fatalf("got %v; expected a proper address with zone identifier", la
)
308 c2
, err
:= Dial(tt
.network
, ls
.PacketConn
.LocalAddr().String())
313 if la
, ok
:= c2
.LocalAddr().(*UDPAddr
); !ok ||
!tt
.nameLookup
&& la
.Zone
== "" {
314 t
.Fatalf("got %v; expected a proper address with zone identifier", la
)
316 if ra
, ok
:= c2
.RemoteAddr().(*UDPAddr
); !ok ||
!tt
.nameLookup
&& ra
.Zone
== "" {
317 t
.Fatalf("got %v; expected a proper address with zone identifier", ra
)
320 if _
, err
:= c2
.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err
!= nil {
323 b
:= make([]byte, 32)
324 if _
, err
:= c2
.Read(b
); err
!= nil {
328 for err
:= range ch
{
329 t
.Errorf("#%d: %v", i
, err
)
334 func TestUDPZeroBytePayload(t
*testing
.T
) {
335 switch runtime
.GOOS
{
336 case "nacl", "plan9":
337 t
.Skipf("not supported on %s", runtime
.GOOS
)
340 c
, err
:= newLocalPacketListener("udp")
346 for _
, genericRead
:= range []bool{false, true} {
347 n
, err
:= c
.WriteTo(nil, c
.LocalAddr())
352 t
.Errorf("got %d; want 0", n
)
354 c
.SetReadDeadline(time
.Now().Add(100 * time
.Millisecond
))
357 _
, err
= c
.(Conn
).Read(b
[:])
359 _
, _
, err
= c
.ReadFrom(b
[:])
362 case nil: // ReadFrom succeeds
363 default: // Read may timeout, it depends on the platform
364 if nerr
, ok
:= err
.(Error
); !ok ||
!nerr
.Timeout() {
371 func TestUDPZeroByteBuffer(t
*testing
.T
) {
372 switch runtime
.GOOS
{
373 case "nacl", "plan9":
374 t
.Skipf("not supported on %s", runtime
.GOOS
)
377 c
, err
:= newLocalPacketListener("udp")
383 b
:= []byte("UDP ZERO BYTE BUFFER TEST")
384 for _
, genericRead
:= range []bool{false, true} {
385 n
, err
:= c
.WriteTo(b
, c
.LocalAddr())
390 t
.Errorf("got %d; want %d", n
, len(b
))
392 c
.SetReadDeadline(time
.Now().Add(100 * time
.Millisecond
))
394 _
, err
= c
.(Conn
).Read(nil)
396 _
, _
, err
= c
.ReadFrom(nil)
399 case nil: // ReadFrom succeeds
400 default: // Read may timeout, it depends on the platform
401 if nerr
, ok
:= err
.(Error
); (!ok ||
!nerr
.Timeout()) && runtime
.GOOS
!= "windows" { // Windows returns WSAEMSGSIZ