blob: 1404b7ce8024bbfffa20b0803be284946b5ade37 [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 Hara4f74bbd2012-11-28 06:36:05 +09008 "reflect"
Mikio Hara974fa752012-01-27 01:31:42 +09009 "runtime"
10 "testing"
Ron Hashimoto3114bd62014-10-10 09:21:32 +110011 "time"
Mikio Hara974fa752012-01-27 01:31:42 +090012)
13
Mikio Hara5a83f062015-04-05 17:00:14 +090014type resolveUDPAddrTest struct {
15 network string
16 litAddrOrName string
17 addr *UDPAddr
18 err error
19}
20
21var resolveUDPAddrTests = []resolveUDPAddrTest{
22 {"udp", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil},
23 {"udp4", "127.0.0.1:65535", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil},
24
25 {"udp", "[::1]:0", &UDPAddr{IP: ParseIP("::1"), Port: 0}, nil},
26 {"udp6", "[::1]:65535", &UDPAddr{IP: ParseIP("::1"), Port: 65535}, nil},
27
28 {"udp", "[::1%en0]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil},
29 {"udp6", "[::1%911]:2", &UDPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil},
30
31 {"", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior
32 {"", "[::1]:0", &UDPAddr{IP: ParseIP("::1"), Port: 0}, nil}, // Go 1.0 behavior
33
34 {"udp", ":12345", &UDPAddr{Port: 12345}, nil},
35
36 {"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
37}
38
Mikio Hara4f74bbd2012-11-28 06:36:05 +090039func TestResolveUDPAddr(t *testing.T) {
Mikio Hara5a83f062015-04-05 17:00:14 +090040 origTestHookLookupIP := testHookLookupIP
41 defer func() { testHookLookupIP = origTestHookLookupIP }()
42 testHookLookupIP = lookupLocalhost
43
44 for i, tt := range resolveUDPAddrTests {
45 addr, err := ResolveUDPAddr(tt.network, tt.litAddrOrName)
Mikio Hara4f74bbd2012-11-28 06:36:05 +090046 if err != tt.err {
Mikio Hara5a83f062015-04-05 17:00:14 +090047 t.Errorf("#%d: %v", i, err)
48 } else if !reflect.DeepEqual(addr, tt.addr) {
49 t.Errorf("#%d: got %#v; want %#v", i, addr, tt.addr)
Mikio Hara4f74bbd2012-11-28 06:36:05 +090050 }
Mikio Hara5a83f062015-04-05 17:00:14 +090051 if err != nil {
52 continue
Russ Coxe8bbbe02013-09-23 22:40:24 -040053 }
Mikio Hara5a83f062015-04-05 17:00:14 +090054 rtaddr, err := ResolveUDPAddr(addr.Network(), addr.String())
55 if err != nil {
56 t.Errorf("#%d: %v", i, err)
57 } else if !reflect.DeepEqual(rtaddr, addr) {
58 t.Errorf("#%d: got %#v; want %#v", i, rtaddr, addr)
Mikio Hara4f74bbd2012-11-28 06:36:05 +090059 }
60 }
61}
62
Mikio Hara974fa752012-01-27 01:31:42 +090063func TestWriteToUDP(t *testing.T) {
Mikio Hara9442c442012-03-06 15:41:17 +090064 switch runtime.GOOS {
65 case "plan9":
Mikio Haraf77e10f2015-05-01 12:38:42 +090066 t.Skipf("not supported on %s", runtime.GOOS)
Mikio Hara974fa752012-01-27 01:31:42 +090067 }
68
Nicolas S. Dade263405e2015-02-04 18:05:53 -080069 c, err := ListenPacket("udp", "127.0.0.1:0")
Mikio Hara974fa752012-01-27 01:31:42 +090070 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -080071 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +090072 }
Nicolas S. Dade263405e2015-02-04 18:05:53 -080073 defer c.Close()
Mikio Hara974fa752012-01-27 01:31:42 +090074
Nicolas S. Dade263405e2015-02-04 18:05:53 -080075 testWriteToConn(t, c.LocalAddr().String())
76 testWriteToPacketConn(t, c.LocalAddr().String())
Mikio Hara974fa752012-01-27 01:31:42 +090077}
78
79func testWriteToConn(t *testing.T, raddr string) {
80 c, err := Dial("udp", raddr)
81 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -080082 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +090083 }
84 defer c.Close()
85
86 ra, err := ResolveUDPAddr("udp", raddr)
87 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -080088 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +090089 }
90
Mikio Haraf77e10f2015-05-01 12:38:42 +090091 b := []byte("CONNECTED-MODE SOCKET")
92 _, err = c.(*UDPConn).WriteToUDP(b, ra)
Mikio Hara974fa752012-01-27 01:31:42 +090093 if err == nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +090094 t.Fatal("should fail")
Mikio Hara974fa752012-01-27 01:31:42 +090095 }
96 if err != nil && err.(*OpError).Err != ErrWriteToConnected {
Mikio Haraf77e10f2015-05-01 12:38:42 +090097 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
Mikio Hara974fa752012-01-27 01:31:42 +090098 }
Mikio Haraf77e10f2015-05-01 12:38:42 +090099 _, err = c.(*UDPConn).WriteTo(b, ra)
Mikio Hara974fa752012-01-27 01:31:42 +0900100 if err == nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900101 t.Fatal("should fail")
Mikio Hara974fa752012-01-27 01:31:42 +0900102 }
103 if err != nil && err.(*OpError).Err != ErrWriteToConnected {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900104 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
Mikio Hara974fa752012-01-27 01:31:42 +0900105 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900106 _, err = c.Write(b)
Mikio Hara974fa752012-01-27 01:31:42 +0900107 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800108 t.Fatal(err)
109 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900110 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra)
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800111 if err == nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900112 t.Fatal("should fail")
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800113 }
114 if err != nil && err.(*OpError).Err != ErrWriteToConnected {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900115 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800116 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900117 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil)
Mikio Haraf43a8de2015-02-10 17:21:03 +0900118 switch runtime.GOOS {
119 case "nacl", "windows": // see golang.org/issue/9252
120 t.Skipf("not implemented yet on %s", runtime.GOOS)
121 default:
122 if err != nil {
123 t.Fatal(err)
124 }
Mikio Hara974fa752012-01-27 01:31:42 +0900125 }
126}
127
128func testWriteToPacketConn(t *testing.T, raddr string) {
129 c, err := ListenPacket("udp", "127.0.0.1:0")
130 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800131 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900132 }
133 defer c.Close()
134
135 ra, err := ResolveUDPAddr("udp", raddr)
136 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800137 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900138 }
139
Mikio Haraf77e10f2015-05-01 12:38:42 +0900140 b := []byte("UNCONNECTED-MODE SOCKET")
141 _, err = c.(*UDPConn).WriteToUDP(b, ra)
Mikio Hara974fa752012-01-27 01:31:42 +0900142 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800143 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900144 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900145 _, err = c.WriteTo(b, ra)
Mikio Hara974fa752012-01-27 01:31:42 +0900146 if err != nil {
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800147 t.Fatal(err)
Mikio Hara974fa752012-01-27 01:31:42 +0900148 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900149 _, err = c.(*UDPConn).Write(b)
Mikio Hara974fa752012-01-27 01:31:42 +0900150 if err == nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900151 t.Fatal("should fail")
Mikio Hara974fa752012-01-27 01:31:42 +0900152 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900153 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil)
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800154 if err == nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900155 t.Fatal("should fail")
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800156 }
157 if err != nil && err.(*OpError).Err != errMissingAddress {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900158 t.Fatalf("should fail as errMissingAddress: %v", err)
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800159 }
Mikio Haraf77e10f2015-05-01 12:38:42 +0900160 _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra)
Mikio Haraf43a8de2015-02-10 17:21:03 +0900161 switch runtime.GOOS {
162 case "nacl", "windows": // see golang.org/issue/9252
163 t.Skipf("not implemented yet on %s", runtime.GOOS)
164 default:
165 if err != nil {
166 t.Fatal(err)
167 }
Nicolas S. Dade263405e2015-02-04 18:05:53 -0800168 }
Mikio Hara974fa752012-01-27 01:31:42 +0900169}
Mikio Hara677c6e62012-11-13 12:56:28 +0900170
171var udpConnLocalNameTests = []struct {
172 net string
173 laddr *UDPAddr
174}{
175 {"udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}},
176 {"udp4", &UDPAddr{}},
177 {"udp4", nil},
178}
179
180func TestUDPConnLocalName(t *testing.T) {
181 if testing.Short() || !*testExternal {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900182 t.Skip("avoid external network")
Mikio Hara677c6e62012-11-13 12:56:28 +0900183 }
184
185 for _, tt := range udpConnLocalNameTests {
186 c, err := ListenUDP(tt.net, tt.laddr)
187 if err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900188 t.Fatal(err)
Mikio Hara677c6e62012-11-13 12:56:28 +0900189 }
190 defer c.Close()
191 la := c.LocalAddr()
192 if a, ok := la.(*UDPAddr); !ok || a.Port == 0 {
Mikio Harabfb32dc2013-03-23 22:32:19 +0900193 t.Fatalf("got %v; expected a proper address with non-zero port number", la)
194 }
195 }
196}
197
198func TestUDPConnLocalAndRemoteNames(t *testing.T) {
199 for _, laddr := range []string{"", "127.0.0.1:0"} {
200 c1, err := ListenPacket("udp", "127.0.0.1:0")
201 if err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900202 t.Fatal(err)
Mikio Harabfb32dc2013-03-23 22:32:19 +0900203 }
204 defer c1.Close()
205
206 var la *UDPAddr
207 if laddr != "" {
208 var err error
209 if la, err = ResolveUDPAddr("udp", laddr); err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900210 t.Fatal(err)
Mikio Harabfb32dc2013-03-23 22:32:19 +0900211 }
212 }
213 c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr))
214 if err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900215 t.Fatal(err)
Mikio Harabfb32dc2013-03-23 22:32:19 +0900216 }
217 defer c2.Close()
218
219 var connAddrs = [4]struct {
220 got Addr
221 ok bool
222 }{
223 {c1.LocalAddr(), true},
224 {c1.(*UDPConn).RemoteAddr(), false},
225 {c2.LocalAddr(), true},
226 {c2.RemoteAddr(), true},
227 }
228 for _, ca := range connAddrs {
229 if a, ok := ca.got.(*UDPAddr); ok != ca.ok || ok && a.Port == 0 {
230 t.Fatalf("got %v; expected a proper address with non-zero port number", ca.got)
231 }
Mikio Hara677c6e62012-11-13 12:56:28 +0900232 }
233 }
234}
Mikio Haraaa0dda72013-03-23 09:57:40 +0900235
236func TestIPv6LinkLocalUnicastUDP(t *testing.T) {
237 if testing.Short() || !*testExternal {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900238 t.Skip("avoid external network")
Mikio Haraaa0dda72013-03-23 09:57:40 +0900239 }
240 if !supportsIPv6 {
Mikio Haraeeb64b72015-05-14 10:18:10 +0900241 t.Skip("IPv6 is not supported")
Mikio Haraaa0dda72013-03-23 09:57:40 +0900242 }
243
Mikio Haraeeb64b72015-05-14 10:18:10 +0900244 for i, tt := range ipv6LinkLocalUnicastUDPTests {
245 c1, err := ListenPacket(tt.network, tt.address)
Mikio Haraaa0dda72013-03-23 09:57:40 +0900246 if err != nil {
247 // It might return "LookupHost returned no
248 // suitable address" error on some platforms.
Mikio Haraf77e10f2015-05-01 12:38:42 +0900249 t.Log(err)
Mikio Haraaa0dda72013-03-23 09:57:40 +0900250 continue
251 }
Mikio Haraeeb64b72015-05-14 10:18:10 +0900252 ls, err := (&packetListener{PacketConn: c1}).newLocalServer()
253 if err != nil {
254 t.Fatal(err)
255 }
256 defer ls.teardown()
257 ch := make(chan error, 1)
258 handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, ch) }
259 if err := ls.buildup(handler); err != nil {
260 t.Fatal(err)
261 }
Mikio Haraaa0dda72013-03-23 09:57:40 +0900262 if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
263 t.Fatalf("got %v; expected a proper address with zone identifier", la)
264 }
265
Mikio Haraeeb64b72015-05-14 10:18:10 +0900266 c2, err := Dial(tt.network, ls.PacketConn.LocalAddr().String())
Mikio Haraaa0dda72013-03-23 09:57:40 +0900267 if err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900268 t.Fatal(err)
Mikio Haraaa0dda72013-03-23 09:57:40 +0900269 }
270 defer c2.Close()
271 if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
272 t.Fatalf("got %v; expected a proper address with zone identifier", la)
273 }
274 if ra, ok := c2.RemoteAddr().(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
275 t.Fatalf("got %v; expected a proper address with zone identifier", ra)
276 }
277
278 if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900279 t.Fatal(err)
Mikio Haraaa0dda72013-03-23 09:57:40 +0900280 }
281 b := make([]byte, 32)
Mikio Haraeeb64b72015-05-14 10:18:10 +0900282 if _, err := c2.Read(b); err != nil {
Mikio Haraf77e10f2015-05-01 12:38:42 +0900283 t.Fatal(err)
Mikio Haraeeb64b72015-05-14 10:18:10 +0900284 }
285
286 for err := range ch {
287 t.Errorf("#%d: %v", i, err)
Mikio Haraaa0dda72013-03-23 09:57:40 +0900288 }
289 }
290}
Mikio Hara03eb1322015-04-20 23:15:00 +0900291
292func TestUDPZeroBytePayload(t *testing.T) {
293 switch runtime.GOOS {
294 case "nacl", "plan9":
295 t.Skipf("not supported on %s", runtime.GOOS)
296 }
297
298 c, err := newLocalPacketListener("udp")
299 if err != nil {
300 t.Fatal(err)
301 }
302 defer c.Close()
303
304 for _, genericRead := range []bool{false, true} {
305 n, err := c.WriteTo(nil, c.LocalAddr())
306 if err != nil {
307 t.Fatal(err)
308 }
309 if n != 0 {
310 t.Errorf("got %d; want 0", n)
311 }
312 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
313 var b [1]byte
314 if genericRead {
315 _, err = c.(Conn).Read(b[:])
316 } else {
317 _, _, err = c.ReadFrom(b[:])
318 }
319 switch err {
320 case nil: // ReadFrom succeeds
321 default: // Read may timeout, it depends on the platform
322 if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
323 t.Fatal(err)
324 }
325 }
326 }
327}
328
329func TestUDPZeroByteBuffer(t *testing.T) {
330 switch runtime.GOOS {
331 case "nacl", "plan9":
332 t.Skipf("not supported on %s", runtime.GOOS)
333 }
334
335 c, err := newLocalPacketListener("udp")
336 if err != nil {
337 t.Fatal(err)
338 }
339 defer c.Close()
340
Mikio Haraf77e10f2015-05-01 12:38:42 +0900341 b := []byte("UDP ZERO BYTE BUFFER TEST")
Mikio Hara03eb1322015-04-20 23:15:00 +0900342 for _, genericRead := range []bool{false, true} {
343 n, err := c.WriteTo(b, c.LocalAddr())
344 if err != nil {
345 t.Fatal(err)
346 }
347 if n != len(b) {
348 t.Errorf("got %d; want %d", n, len(b))
349 }
350 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
351 if genericRead {
352 _, err = c.(Conn).Read(nil)
353 } else {
354 _, _, err = c.ReadFrom(nil)
355 }
356 switch err {
357 case nil: // ReadFrom succeeds
358 default: // Read may timeout, it depends on the platform
Martin Möhrmannfdd01792016-02-24 11:55:20 +0100359 if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows returns WSAEMSGSIZ
Mikio Hara03eb1322015-04-20 23:15:00 +0900360 t.Fatal(err)
361 }
362 }
363 }
364}