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