github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/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 "internal/testenv" 11 "reflect" 12 "runtime" 13 "testing" 14 "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 switch runtime.GOOS { 166 case "nacl": // see golang.org/issue/9252 167 t.Skipf("not implemented yet on %s", runtime.GOOS) 168 default: 169 if err != nil { 170 t.Fatal(err) 171 } 172 } 173 } 174 175 func testWriteToPacketConn(t *testing.T, raddr string) { 176 c, err := ListenPacket("udp", "127.0.0.1:0") 177 if err != nil { 178 t.Fatal(err) 179 } 180 defer c.Close() 181 182 ra, err := ResolveUDPAddr("udp", raddr) 183 if err != nil { 184 t.Fatal(err) 185 } 186 187 b := []byte("UNCONNECTED-MODE SOCKET") 188 _, err = c.(*UDPConn).WriteToUDP(b, ra) 189 if err != nil { 190 t.Fatal(err) 191 } 192 _, err = c.WriteTo(b, ra) 193 if err != nil { 194 t.Fatal(err) 195 } 196 _, err = c.(*UDPConn).Write(b) 197 if err == nil { 198 t.Fatal("should fail") 199 } 200 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil) 201 if err == nil { 202 t.Fatal("should fail") 203 } 204 if err != nil && err.(*OpError).Err != errMissingAddress { 205 t.Fatalf("should fail as errMissingAddress: %v", err) 206 } 207 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra) 208 switch runtime.GOOS { 209 case "nacl": // see golang.org/issue/9252 210 t.Skipf("not implemented yet on %s", runtime.GOOS) 211 default: 212 if err != nil { 213 t.Fatal(err) 214 } 215 } 216 } 217 218 var udpConnLocalNameTests = []struct { 219 net string 220 laddr *UDPAddr 221 }{ 222 {"udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}}, 223 {"udp4", &UDPAddr{}}, 224 {"udp4", nil}, 225 } 226 227 func TestUDPConnLocalName(t *testing.T) { 228 testenv.MustHaveExternalNetwork(t) 229 230 for _, tt := range udpConnLocalNameTests { 231 c, err := ListenUDP(tt.net, tt.laddr) 232 if err != nil { 233 t.Fatal(err) 234 } 235 defer c.Close() 236 la := c.LocalAddr() 237 if a, ok := la.(*UDPAddr); !ok || a.Port == 0 { 238 t.Fatalf("got %v; expected a proper address with non-zero port number", la) 239 } 240 } 241 } 242 243 func TestUDPConnLocalAndRemoteNames(t *testing.T) { 244 for _, laddr := range []string{"", "127.0.0.1:0"} { 245 c1, err := ListenPacket("udp", "127.0.0.1:0") 246 if err != nil { 247 t.Fatal(err) 248 } 249 defer c1.Close() 250 251 var la *UDPAddr 252 if laddr != "" { 253 var err error 254 if la, err = ResolveUDPAddr("udp", laddr); err != nil { 255 t.Fatal(err) 256 } 257 } 258 c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr)) 259 if err != nil { 260 t.Fatal(err) 261 } 262 defer c2.Close() 263 264 var connAddrs = [4]struct { 265 got Addr 266 ok bool 267 }{ 268 {c1.LocalAddr(), true}, 269 {c1.(*UDPConn).RemoteAddr(), false}, 270 {c2.LocalAddr(), true}, 271 {c2.RemoteAddr(), true}, 272 } 273 for _, ca := range connAddrs { 274 if a, ok := ca.got.(*UDPAddr); ok != ca.ok || ok && a.Port == 0 { 275 t.Fatalf("got %v; expected a proper address with non-zero port number", ca.got) 276 } 277 } 278 } 279 } 280 281 func TestIPv6LinkLocalUnicastUDP(t *testing.T) { 282 testenv.MustHaveExternalNetwork(t) 283 284 if !supportsIPv6() { 285 t.Skip("IPv6 is not supported") 286 } 287 288 for i, tt := range ipv6LinkLocalUnicastUDPTests { 289 c1, err := ListenPacket(tt.network, tt.address) 290 if err != nil { 291 // It might return "LookupHost returned no 292 // suitable address" error on some platforms. 293 t.Log(err) 294 continue 295 } 296 ls, err := (&packetListener{PacketConn: c1}).newLocalServer() 297 if err != nil { 298 t.Fatal(err) 299 } 300 defer ls.teardown() 301 ch := make(chan error, 1) 302 handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, ch) } 303 if err := ls.buildup(handler); err != nil { 304 t.Fatal(err) 305 } 306 if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" { 307 t.Fatalf("got %v; expected a proper address with zone identifier", la) 308 } 309 310 c2, err := Dial(tt.network, ls.PacketConn.LocalAddr().String()) 311 if err != nil { 312 t.Fatal(err) 313 } 314 defer c2.Close() 315 if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" { 316 t.Fatalf("got %v; expected a proper address with zone identifier", la) 317 } 318 if ra, ok := c2.RemoteAddr().(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" { 319 t.Fatalf("got %v; expected a proper address with zone identifier", ra) 320 } 321 322 if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err != nil { 323 t.Fatal(err) 324 } 325 b := make([]byte, 32) 326 if _, err := c2.Read(b); err != nil { 327 t.Fatal(err) 328 } 329 330 for err := range ch { 331 t.Errorf("#%d: %v", i, err) 332 } 333 } 334 } 335 336 func TestUDPZeroBytePayload(t *testing.T) { 337 switch runtime.GOOS { 338 case "nacl", "plan9": 339 t.Skipf("not supported on %s", runtime.GOOS) 340 } 341 342 c, err := newLocalPacketListener("udp") 343 if err != nil { 344 t.Fatal(err) 345 } 346 defer c.Close() 347 348 for _, genericRead := range []bool{false, true} { 349 n, err := c.WriteTo(nil, c.LocalAddr()) 350 if err != nil { 351 t.Fatal(err) 352 } 353 if n != 0 { 354 t.Errorf("got %d; want 0", n) 355 } 356 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 357 var b [1]byte 358 if genericRead { 359 _, err = c.(Conn).Read(b[:]) 360 // Read may timeout, it depends on the platform. 361 if err != nil { 362 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 363 t.Fatal(err) 364 } 365 } 366 } else { 367 _, _, err = c.ReadFrom(b[:]) 368 if err != nil { 369 t.Fatal(err) 370 } 371 } 372 } 373 } 374 375 func TestUDPZeroByteBuffer(t *testing.T) { 376 switch runtime.GOOS { 377 case "nacl", "plan9": 378 t.Skipf("not supported on %s", runtime.GOOS) 379 } 380 381 c, err := newLocalPacketListener("udp") 382 if err != nil { 383 t.Fatal(err) 384 } 385 defer c.Close() 386 387 b := []byte("UDP ZERO BYTE BUFFER TEST") 388 for _, genericRead := range []bool{false, true} { 389 n, err := c.WriteTo(b, c.LocalAddr()) 390 if err != nil { 391 t.Fatal(err) 392 } 393 if n != len(b) { 394 t.Errorf("got %d; want %d", n, len(b)) 395 } 396 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 397 if genericRead { 398 _, err = c.(Conn).Read(nil) 399 } else { 400 _, _, err = c.ReadFrom(nil) 401 } 402 switch err { 403 case nil: // ReadFrom succeeds 404 default: // Read may timeout, it depends on the platform 405 if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows returns WSAEMSGSIZE 406 t.Fatal(err) 407 } 408 } 409 } 410 } 411 412 func TestUDPReadSizeError(t *testing.T) { 413 switch runtime.GOOS { 414 case "nacl", "plan9": 415 t.Skipf("not supported on %s", runtime.GOOS) 416 } 417 418 c1, err := newLocalPacketListener("udp") 419 if err != nil { 420 t.Fatal(err) 421 } 422 defer c1.Close() 423 424 c2, err := Dial("udp", c1.LocalAddr().String()) 425 if err != nil { 426 t.Fatal(err) 427 } 428 defer c2.Close() 429 430 b1 := []byte("READ SIZE ERROR TEST") 431 for _, genericRead := range []bool{false, true} { 432 n, err := c2.Write(b1) 433 if err != nil { 434 t.Fatal(err) 435 } 436 if n != len(b1) { 437 t.Errorf("got %d; want %d", n, len(b1)) 438 } 439 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 440 b2 := make([]byte, len(b1)-1) 441 if genericRead { 442 n, err = c1.(Conn).Read(b2) 443 } else { 444 n, _, err = c1.ReadFrom(b2) 445 } 446 switch err { 447 case nil: // ReadFrom succeeds 448 default: // Read may timeout, it depends on the platform 449 if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows returns WSAEMSGSIZE 450 t.Fatal(err) 451 } 452 } 453 if n != len(b1)-1 { 454 t.Fatalf("got %d; want %d", n, len(b1)-1) 455 } 456 } 457 }