github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/net/udpsock_test.go (about) 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. 4 5 // +build !js 6 7 package net 8 9 import ( 10 "github.com/x04/go/src/internal/testenv" 11 "github.com/x04/go/src/reflect" 12 "github.com/x04/go/src/runtime" 13 "github.com/x04/go/src/testing" 14 "github.com/x04/go/src/time" 15 ) 16 17 func BenchmarkUDP6LinkLocalUnicast(b *testing.B) { 18 testHookUninstaller.Do(uninstallTestHooks) 19 20 if !supportsIPv6() { 21 b.Skip("IPv6 is not supported") 22 } 23 ifi := loopbackInterface() 24 if ifi == nil { 25 b.Skip("loopback interface not found") 26 } 27 lla := ipv6LinkLocalUnicastAddr(ifi) 28 if lla == "" { 29 b.Skip("IPv6 link-local unicast address not found") 30 } 31 32 c1, err := ListenPacket("udp6", JoinHostPort(lla+"%"+ifi.Name, "0")) 33 if err != nil { 34 b.Fatal(err) 35 } 36 defer c1.Close() 37 c2, err := ListenPacket("udp6", JoinHostPort(lla+"%"+ifi.Name, "0")) 38 if err != nil { 39 b.Fatal(err) 40 } 41 defer c2.Close() 42 43 var buf [1]byte 44 for i := 0; i < b.N; i++ { 45 if _, err := c1.WriteTo(buf[:], c2.LocalAddr()); err != nil { 46 b.Fatal(err) 47 } 48 if _, _, err := c2.ReadFrom(buf[:]); err != nil { 49 b.Fatal(err) 50 } 51 } 52 } 53 54 type resolveUDPAddrTest struct { 55 network string 56 litAddrOrName string 57 addr *UDPAddr 58 err error 59 } 60 61 var resolveUDPAddrTests = []resolveUDPAddrTest{ 62 {"udp", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, 63 {"udp4", "127.0.0.1:65535", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil}, 64 65 {"udp", "[::1]:0", &UDPAddr{IP: ParseIP("::1"), Port: 0}, nil}, 66 {"udp6", "[::1]:65535", &UDPAddr{IP: ParseIP("::1"), Port: 65535}, nil}, 67 68 {"udp", "[::1%en0]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil}, 69 {"udp6", "[::1%911]:2", &UDPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil}, 70 71 {"", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior 72 {"", "[::1]:0", &UDPAddr{IP: ParseIP("::1"), Port: 0}, nil}, // Go 1.0 behavior 73 74 {"udp", ":12345", &UDPAddr{Port: 12345}, nil}, 75 76 {"http", "127.0.0.1:0", nil, UnknownNetworkError("http")}, 77 78 {"udp", "127.0.0.1:domain", &UDPAddr{IP: ParseIP("127.0.0.1"), Port: 53}, nil}, 79 {"udp", "[::ffff:127.0.0.1]:domain", &UDPAddr{IP: ParseIP("::ffff:127.0.0.1"), Port: 53}, nil}, 80 {"udp", "[2001:db8::1]:domain", &UDPAddr{IP: ParseIP("2001:db8::1"), Port: 53}, nil}, 81 {"udp4", "127.0.0.1:domain", &UDPAddr{IP: ParseIP("127.0.0.1"), Port: 53}, nil}, 82 {"udp4", "[::ffff:127.0.0.1]:domain", &UDPAddr{IP: ParseIP("127.0.0.1"), Port: 53}, nil}, 83 {"udp6", "[2001:db8::1]:domain", &UDPAddr{IP: ParseIP("2001:db8::1"), Port: 53}, nil}, 84 85 {"udp4", "[2001:db8::1]:domain", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "2001:db8::1"}}, 86 {"udp6", "127.0.0.1:domain", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "127.0.0.1"}}, 87 {"udp6", "[::ffff:127.0.0.1]:domain", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "::ffff:127.0.0.1"}}, 88 } 89 90 func TestResolveUDPAddr(t *testing.T) { 91 origTestHookLookupIP := testHookLookupIP 92 defer func() { testHookLookupIP = origTestHookLookupIP }() 93 testHookLookupIP = lookupLocalhost 94 95 for _, tt := range resolveUDPAddrTests { 96 addr, err := ResolveUDPAddr(tt.network, tt.litAddrOrName) 97 if !reflect.DeepEqual(addr, tt.addr) || !reflect.DeepEqual(err, tt.err) { 98 t.Errorf("ResolveUDPAddr(%q, %q) = %#v, %v, want %#v, %v", tt.network, tt.litAddrOrName, addr, err, tt.addr, tt.err) 99 continue 100 } 101 if err == nil { 102 addr2, err := ResolveUDPAddr(addr.Network(), addr.String()) 103 if !reflect.DeepEqual(addr2, tt.addr) || err != tt.err { 104 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) 105 } 106 } 107 } 108 } 109 110 func TestWriteToUDP(t *testing.T) { 111 switch runtime.GOOS { 112 case "plan9": 113 t.Skipf("not supported on %s", runtime.GOOS) 114 } 115 116 c, err := ListenPacket("udp", "127.0.0.1:0") 117 if err != nil { 118 t.Fatal(err) 119 } 120 defer c.Close() 121 122 testWriteToConn(t, c.LocalAddr().String()) 123 testWriteToPacketConn(t, c.LocalAddr().String()) 124 } 125 126 func testWriteToConn(t *testing.T, raddr string) { 127 c, err := Dial("udp", raddr) 128 if err != nil { 129 t.Fatal(err) 130 } 131 defer c.Close() 132 133 ra, err := ResolveUDPAddr("udp", raddr) 134 if err != nil { 135 t.Fatal(err) 136 } 137 138 b := []byte("CONNECTED-MODE SOCKET") 139 _, err = c.(*UDPConn).WriteToUDP(b, ra) 140 if err == nil { 141 t.Fatal("should fail") 142 } 143 if err != nil && err.(*OpError).Err != ErrWriteToConnected { 144 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 145 } 146 _, err = c.(*UDPConn).WriteTo(b, ra) 147 if err == nil { 148 t.Fatal("should fail") 149 } 150 if err != nil && err.(*OpError).Err != ErrWriteToConnected { 151 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 152 } 153 _, err = c.Write(b) 154 if err != nil { 155 t.Fatal(err) 156 } 157 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra) 158 if err == nil { 159 t.Fatal("should fail") 160 } 161 if err != nil && err.(*OpError).Err != ErrWriteToConnected { 162 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 163 } 164 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil) 165 if err != nil { 166 t.Fatal(err) 167 } 168 } 169 170 func testWriteToPacketConn(t *testing.T, raddr string) { 171 c, err := ListenPacket("udp", "127.0.0.1:0") 172 if err != nil { 173 t.Fatal(err) 174 } 175 defer c.Close() 176 177 ra, err := ResolveUDPAddr("udp", raddr) 178 if err != nil { 179 t.Fatal(err) 180 } 181 182 b := []byte("UNCONNECTED-MODE SOCKET") 183 _, err = c.(*UDPConn).WriteToUDP(b, ra) 184 if err != nil { 185 t.Fatal(err) 186 } 187 _, err = c.WriteTo(b, ra) 188 if err != nil { 189 t.Fatal(err) 190 } 191 _, err = c.(*UDPConn).Write(b) 192 if err == nil { 193 t.Fatal("should fail") 194 } 195 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil) 196 if err == nil { 197 t.Fatal("should fail") 198 } 199 if err != nil && err.(*OpError).Err != errMissingAddress { 200 t.Fatalf("should fail as errMissingAddress: %v", err) 201 } 202 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra) 203 if err != nil { 204 t.Fatal(err) 205 } 206 } 207 208 var udpConnLocalNameTests = []struct { 209 net string 210 laddr *UDPAddr 211 }{ 212 {"udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}}, 213 {"udp4", &UDPAddr{}}, 214 {"udp4", nil}, 215 } 216 217 func TestUDPConnLocalName(t *testing.T) { 218 testenv.MustHaveExternalNetwork(t) 219 220 for _, tt := range udpConnLocalNameTests { 221 c, err := ListenUDP(tt.net, tt.laddr) 222 if err != nil { 223 t.Fatal(err) 224 } 225 defer c.Close() 226 la := c.LocalAddr() 227 if a, ok := la.(*UDPAddr); !ok || a.Port == 0 { 228 t.Fatalf("got %v; expected a proper address with non-zero port number", la) 229 } 230 } 231 } 232 233 func TestUDPConnLocalAndRemoteNames(t *testing.T) { 234 for _, laddr := range []string{"", "127.0.0.1:0"} { 235 c1, err := ListenPacket("udp", "127.0.0.1:0") 236 if err != nil { 237 t.Fatal(err) 238 } 239 defer c1.Close() 240 241 var la *UDPAddr 242 if laddr != "" { 243 var err error 244 if la, err = ResolveUDPAddr("udp", laddr); err != nil { 245 t.Fatal(err) 246 } 247 } 248 c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr)) 249 if err != nil { 250 t.Fatal(err) 251 } 252 defer c2.Close() 253 254 var connAddrs = [4]struct { 255 got Addr 256 ok bool 257 }{ 258 {c1.LocalAddr(), true}, 259 {c1.(*UDPConn).RemoteAddr(), false}, 260 {c2.LocalAddr(), true}, 261 {c2.RemoteAddr(), true}, 262 } 263 for _, ca := range connAddrs { 264 if a, ok := ca.got.(*UDPAddr); ok != ca.ok || ok && a.Port == 0 { 265 t.Fatalf("got %v; expected a proper address with non-zero port number", ca.got) 266 } 267 } 268 } 269 } 270 271 func TestIPv6LinkLocalUnicastUDP(t *testing.T) { 272 testenv.MustHaveExternalNetwork(t) 273 274 if !supportsIPv6() { 275 t.Skip("IPv6 is not supported") 276 } 277 278 for i, tt := range ipv6LinkLocalUnicastUDPTests { 279 c1, err := ListenPacket(tt.network, tt.address) 280 if err != nil { 281 // It might return "LookupHost returned no 282 // suitable address" error on some platforms. 283 t.Log(err) 284 continue 285 } 286 ls, err := (&packetListener{PacketConn: c1}).newLocalServer() 287 if err != nil { 288 t.Fatal(err) 289 } 290 defer ls.teardown() 291 ch := make(chan error, 1) 292 handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, ch) } 293 if err := ls.buildup(handler); err != nil { 294 t.Fatal(err) 295 } 296 if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" { 297 t.Fatalf("got %v; expected a proper address with zone identifier", la) 298 } 299 300 c2, err := Dial(tt.network, ls.PacketConn.LocalAddr().String()) 301 if err != nil { 302 t.Fatal(err) 303 } 304 defer c2.Close() 305 if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" { 306 t.Fatalf("got %v; expected a proper address with zone identifier", la) 307 } 308 if ra, ok := c2.RemoteAddr().(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" { 309 t.Fatalf("got %v; expected a proper address with zone identifier", ra) 310 } 311 312 if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err != nil { 313 t.Fatal(err) 314 } 315 b := make([]byte, 32) 316 if _, err := c2.Read(b); err != nil { 317 t.Fatal(err) 318 } 319 320 for err := range ch { 321 t.Errorf("#%d: %v", i, err) 322 } 323 } 324 } 325 326 func TestUDPZeroBytePayload(t *testing.T) { 327 switch runtime.GOOS { 328 case "plan9": 329 t.Skipf("not supported on %s", runtime.GOOS) 330 case "darwin": 331 testenv.SkipFlaky(t, 29225) 332 } 333 334 c, err := newLocalPacketListener("udp") 335 if err != nil { 336 t.Fatal(err) 337 } 338 defer c.Close() 339 340 for _, genericRead := range []bool{false, true} { 341 n, err := c.WriteTo(nil, c.LocalAddr()) 342 if err != nil { 343 t.Fatal(err) 344 } 345 if n != 0 { 346 t.Errorf("got %d; want 0", n) 347 } 348 c.SetReadDeadline(time.Now().Add(30 * time.Second)) 349 var b [1]byte 350 var name string 351 if genericRead { 352 _, err = c.(Conn).Read(b[:]) 353 name = "Read" 354 } else { 355 _, _, err = c.ReadFrom(b[:]) 356 name = "ReadFrom" 357 } 358 if err != nil { 359 t.Errorf("%s of zero byte packet failed: %v", name, err) 360 } 361 } 362 } 363 364 func TestUDPZeroByteBuffer(t *testing.T) { 365 switch runtime.GOOS { 366 case "plan9": 367 t.Skipf("not supported on %s", runtime.GOOS) 368 } 369 370 c, err := newLocalPacketListener("udp") 371 if err != nil { 372 t.Fatal(err) 373 } 374 defer c.Close() 375 376 b := []byte("UDP ZERO BYTE BUFFER TEST") 377 for _, genericRead := range []bool{false, true} { 378 n, err := c.WriteTo(b, c.LocalAddr()) 379 if err != nil { 380 t.Fatal(err) 381 } 382 if n != len(b) { 383 t.Errorf("got %d; want %d", n, len(b)) 384 } 385 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 386 if genericRead { 387 _, err = c.(Conn).Read(nil) 388 } else { 389 _, _, err = c.ReadFrom(nil) 390 } 391 switch err { 392 case nil: // ReadFrom succeeds 393 default: // Read may timeout, it depends on the platform 394 if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows returns WSAEMSGSIZE 395 t.Fatal(err) 396 } 397 } 398 } 399 } 400 401 func TestUDPReadSizeError(t *testing.T) { 402 switch runtime.GOOS { 403 case "plan9": 404 t.Skipf("not supported on %s", runtime.GOOS) 405 } 406 407 c1, err := newLocalPacketListener("udp") 408 if err != nil { 409 t.Fatal(err) 410 } 411 defer c1.Close() 412 413 c2, err := Dial("udp", c1.LocalAddr().String()) 414 if err != nil { 415 t.Fatal(err) 416 } 417 defer c2.Close() 418 419 b1 := []byte("READ SIZE ERROR TEST") 420 for _, genericRead := range []bool{false, true} { 421 n, err := c2.Write(b1) 422 if err != nil { 423 t.Fatal(err) 424 } 425 if n != len(b1) { 426 t.Errorf("got %d; want %d", n, len(b1)) 427 } 428 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 429 b2 := make([]byte, len(b1)-1) 430 if genericRead { 431 n, err = c1.(Conn).Read(b2) 432 } else { 433 n, _, err = c1.ReadFrom(b2) 434 } 435 switch err { 436 case nil: // ReadFrom succeeds 437 default: // Read may timeout, it depends on the platform 438 if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows returns WSAEMSGSIZE 439 t.Fatal(err) 440 } 441 } 442 if n != len(b1)-1 { 443 t.Fatalf("got %d; want %d", n, len(b1)-1) 444 } 445 } 446 }