blob: 29d769c5a5864076c93814aa8661afce347ace53 [file] [log] [blame]
Brad Fitzpatrick51947442016-03-01 22:57:46 +00001// Copyright 2012 The Go Authors. All rights reserved.
Mikio Hara974fa752012-01-27 01:31:42 +09002// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package net
6
7import (
Mikio Haraed7cd252016-04-14 12:17:44 +09008 "internal/testenv"
Mikio Hara4f74bbd2012-11-28 06:36:05 +09009 "reflect"
Mikio Hara974fa752012-01-27 01:31:42 +090010 "runtime"
11 "testing"
Ron Hashimoto3114bd62014-10-10 09:21:32 +110012 "time"
Mikio Hara974fa752012-01-27 01:31:42 +090013)
14
Mikio Hara1d214f72016-04-13 06:19:53 +090015func 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
Mikio Hara5a83f062015-04-05 17:00:14 +090052type resolveUDPAddrTest struct {
53 network string
54 litAddrOrName string
55 addr *UDPAddr
56 err error
57}
58
59var 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
Mikio Hara4f74bbd2012-11-28 06:36:05 +090077func TestResolveUDPAddr(t *testing.T) {
Mikio Hara5a83f062015-04-05 17:00:14 +090078 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)
Mikio Hara4f74bbd2012-11-28 06:36:05 +090084 if err != tt.err {
Mikio Hara5a83f062015-04-05 17:00:14 +090085 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)
Mikio Hara4f74bbd2012-11-28 06:36:05 +090088 }
Mikio Hara5a83f062015-04-05 17:00:14 +090089 if err != nil {
90 continue
Russ Coxe8bbbe02013-09-23 22:40:24 -040091 }
Mikio Hara5a83f062015-04-05 17:00:14 +090092 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)
Mikio Hara4f74bbd2012-11-28 06:36:05 +090097 }
98 }
99}
100
Mikio Hara974fa752012-01-27 01:31:42 +0900101func TestWriteToUDP(t *testing.T) {
Mikio Hara9442c442012-03-06 15:41:17 +0900102 switch runtime.GOOS {
103 case "plan9":
Mikio Haraf77e10f2015-05-01 12:38:42 +0900104 t.Skipf("not supported on %s", runtime.GOOS)
Mikio Hara974fa752012-01-27 01:31:42 +0900105 }
106
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800107 c, err := ListenPacket("udp", "127.0.0.1:0")
Mikio Hara974fa752012-01-27 01:31:42 +0900108 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800109 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900110 }
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800111 defer c.Close()
Mikio Hara974fa752012-01-27 01:31:42 +0900112
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800113 testWriteToConn(t, c.LocalAddr().String())
114 testWriteToPacketConn(t, c.LocalAddr().String())
Mikio Hara974fa752012-01-27 01:31:42 +0900115}
116
117func testWriteToConn(t *testing.T, raddr string) {
118 c, err := Dial("udp", raddr)
119 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800120 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900121 }
122 defer c.Close()
123
124 ra, err := ResolveUDPAddr("udp", raddr)
125 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800126 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900127 }
128
Mikio Haraf77e10f2015-05-01 12:38:42 +0900129 b := []byte("CONNECTED-MODE SOCKET")
130 _, err = c.(*UDPConn).WriteToUDP(b, ra)
Mikio Hara974fa752012-01-27 01:31:42 +0900131 if err == nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900132 t.Fatal("should fail")
Mikio Hara974fa752012-01-27 01:31:42 +0900133 }
134 if err != nil && err.(*OpError).Err != ErrWriteToConnected {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900135 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
Mikio Hara974fa752012-01-27 01:31:42 +0900136 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900137 _, err = c.(*UDPConn).WriteTo(b, ra)
Mikio Hara974fa752012-01-27 01:31:42 +0900138 if err == nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900139 t.Fatal("should fail")
Mikio Hara974fa752012-01-27 01:31:42 +0900140 }
141 if err != nil && err.(*OpError).Err != ErrWriteToConnected {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900142 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
Mikio Hara974fa752012-01-27 01:31:42 +0900143 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900144 _, err = c.Write(b)
Mikio Hara974fa752012-01-27 01:31:42 +0900145 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800146 t.Fatal(err)
147 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900148 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra)
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800149 if err == nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900150 t.Fatal("should fail")
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800151 }
152 if err != nil && err.(*OpError).Err != ErrWriteToConnected {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900153 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800154 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900155 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil)
Mikio Haraf43a8de2015-02-10 17:21:03 +0900156 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 }
Mikio Hara974fa752012-01-27 01:31:42 +0900163 }
164}
165
166func testWriteToPacketConn(t *testing.T, raddr string) {
167 c, err := ListenPacket("udp", "127.0.0.1:0")
168 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800169 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900170 }
171 defer c.Close()
172
173 ra, err := ResolveUDPAddr("udp", raddr)
174 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800175 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900176 }
177
Mikio Haraf77e10f2015-05-01 12:38:42 +0900178 b := []byte("UNCONNECTED-MODE SOCKET")
179 _, err = c.(*UDPConn).WriteToUDP(b, ra)
Mikio Hara974fa752012-01-27 01:31:42 +0900180 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800181 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900182 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900183 _, err = c.WriteTo(b, ra)
Mikio Hara974fa752012-01-27 01:31:42 +0900184 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800185 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900186 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900187 _, err = c.(*UDPConn).Write(b)
Mikio Hara974fa752012-01-27 01:31:42 +0900188 if err == nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900189 t.Fatal("should fail")
Mikio Hara974fa752012-01-27 01:31:42 +0900190 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900191 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil)
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800192 if err == nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900193 t.Fatal("should fail")
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800194 }
195 if err != nil && err.(*OpError).Err != errMissingAddress {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900196 t.Fatalf("should fail as errMissingAddress: %v", err)
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800197 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900198 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra)
Mikio Haraf43a8de2015-02-10 17:21:03 +0900199 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 }
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800206 }
Mikio Hara974fa752012-01-27 01:31:42 +0900207}
Mikio Hara677c6e62012-11-13 12:56:28 +0900208
209var 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
218func TestUDPConnLocalName(t *testing.T) {
Mikio Haraed7cd252016-04-14 12:17:44 +0900219 testenv.MustHaveExternalNetwork(t)
Mikio Hara677c6e62012-11-13 12:56:28 +0900220
221 for _, tt := range udpConnLocalNameTests {
222 c, err := ListenUDP(tt.net, tt.laddr)
223 if err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900224 t.Fatal(err)
Mikio Hara677c6e62012-11-13 12:56:28 +0900225 }
226 defer c.Close()
227 la := c.LocalAddr()
228 if a, ok := la.(*UDPAddr); !ok || a.Port == 0 {
Mikio Harabfb32dc2013-03-23 22:32:19 +0900229 t.Fatalf("got %v; expected a proper address with non-zero port number", la)
230 }
231 }
232}
233
234func 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 {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900238 t.Fatal(err)
Mikio Harabfb32dc2013-03-23 22:32:19 +0900239 }
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 {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900246 t.Fatal(err)
Mikio Harabfb32dc2013-03-23 22:32:19 +0900247 }
248 }
249 c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr))
250 if err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900251 t.Fatal(err)
Mikio Harabfb32dc2013-03-23 22:32:19 +0900252 }
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 }
Mikio Hara677c6e62012-11-13 12:56:28 +0900268 }
269 }
270}
Mikio Haraaa0dda72013-03-23 09:57:40 +0900271
272func TestIPv6LinkLocalUnicastUDP(t *testing.T) {
Mikio Haraed7cd252016-04-14 12:17:44 +0900273 testenv.MustHaveExternalNetwork(t)
274
Mikio Haraaa0dda72013-03-23 09:57:40 +0900275 if !supportsIPv6 {
Mikio Haraeeb64b72015-05-14 10:18:10 +0900276 t.Skip("IPv6 is not supported")
Mikio Haraaa0dda72013-03-23 09:57:40 +0900277 }
278
Mikio Haraeeb64b72015-05-14 10:18:10 +0900279 for i, tt := range ipv6LinkLocalUnicastUDPTests {
280 c1, err := ListenPacket(tt.network, tt.address)
Mikio Haraaa0dda72013-03-23 09:57:40 +0900281 if err != nil {
282 // It might return "LookupHost returned no
283 // suitable address" error on some platforms.
Mikio Haraf77e10f2015-05-01 12:38:42 +0900284 t.Log(err)
Mikio Haraaa0dda72013-03-23 09:57:40 +0900285 continue
286 }
Mikio Haraeeb64b72015-05-14 10:18:10 +0900287 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 }
Mikio Haraaa0dda72013-03-23 09:57:40 +0900297 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
Mikio Haraeeb64b72015-05-14 10:18:10 +0900301 c2, err := Dial(tt.network, ls.PacketConn.LocalAddr().String())
Mikio Haraaa0dda72013-03-23 09:57:40 +0900302 if err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900303 t.Fatal(err)
Mikio Haraaa0dda72013-03-23 09:57:40 +0900304 }
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 {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900314 t.Fatal(err)
Mikio Haraaa0dda72013-03-23 09:57:40 +0900315 }
316 b := make([]byte, 32)
Mikio Haraeeb64b72015-05-14 10:18:10 +0900317 if _, err := c2.Read(b); err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900318 t.Fatal(err)
Mikio Haraeeb64b72015-05-14 10:18:10 +0900319 }
320
321 for err := range ch {
322 t.Errorf("#%d: %v", i, err)
Mikio Haraaa0dda72013-03-23 09:57:40 +0900323 }
324 }
325}
Mikio Hara03eb1322015-04-20 23:15:00 +0900326
327func 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
364func 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
Mikio Haraf77e10f2015-05-01 12:38:42 +0900376 b := []byte("UDP ZERO BYTE BUFFER TEST")
Mikio Hara03eb1322015-04-20 23:15:00 +0900377 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
Martin Möhrmannfdd01792016-02-24 11:55:20 +0100394 if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows returns WSAEMSGSIZ
Mikio Hara03eb1322015-04-20 23:15:00 +0900395 t.Fatal(err)
396 }
397 }
398 }
399}