LEFT | RIGHT |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package net | 5 package net |
6 | 6 |
7 import ( | 7 import ( |
| 8 "fmt" |
8 "reflect" | 9 "reflect" |
9 "runtime" | 10 "runtime" |
10 "testing" | 11 "testing" |
11 ) | 12 ) |
12 | 13 |
13 var resolveUDPAddrTests = []struct { | 14 var resolveUDPAddrTests = []struct { |
14 net string | 15 net string |
15 litAddr string | 16 litAddr string |
16 addr *UDPAddr | 17 addr *UDPAddr |
17 err error | 18 err error |
18 }{ | 19 }{ |
19 {"udp", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, | 20 {"udp", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, |
20 {"udp4", "127.0.0.1:65535", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535
}, nil}, | 21 {"udp4", "127.0.0.1:65535", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535
}, nil}, |
21 | 22 |
22 {"udp", "[::1]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1}, nil}, | 23 {"udp", "[::1]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1}, nil}, |
23 {"udp6", "[::1]:65534", &UDPAddr{IP: ParseIP("::1"), Port: 65534}, nil}, | 24 {"udp6", "[::1]:65534", &UDPAddr{IP: ParseIP("::1"), Port: 65534}, nil}, |
24 | 25 |
25 {"udp", "[::1%en0]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"
}, nil}, | 26 {"udp", "[::1%en0]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"
}, nil}, |
26 {"udp6", "[::1%911]:2", &UDPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911
"}, nil}, | 27 {"udp6", "[::1%911]:2", &UDPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911
"}, nil}, |
27 » {"udp6", "[::1]:3", &UDPAddr{IP: ParseIP("::1"), Port: 3, Zone: "loopbac
k"}, nil}, | 28 » {"udp6", "[fe80::1]:3", &UDPAddr{IP: ParseIP("fe80::1"), Port: 3, Zone:
"name"}, nil}, |
| 29 » {"udp6", "[fe80::1]:4", &UDPAddr{IP: ParseIP("fe80::1"), Port: 4, Zone:
"index"}, 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 |
28 | 33 |
29 {"sip", "127.0.0.1:0", nil, UnknownNetworkError("sip")}, | 34 {"sip", "127.0.0.1:0", nil, UnknownNetworkError("sip")}, |
30 } | 35 } |
31 | 36 |
32 func TestResolveUDPAddr(t *testing.T) { | 37 func TestResolveUDPAddr(t *testing.T) { |
33 for _, tt := range resolveUDPAddrTests { | 38 for _, tt := range resolveUDPAddrTests { |
34 » » if tt.addr != nil && tt.addr.Zone == "loopback" { | 39 » » if tt.addr != nil && (tt.addr.Zone == "name" || tt.addr.Zone ==
"index") { |
35 ifi := loopbackInterface() | 40 ifi := loopbackInterface() |
36 if ifi == nil { | 41 if ifi == nil { |
37 continue | 42 continue |
38 } | 43 } |
39 i := last(tt.litAddr, ']') | 44 i := last(tt.litAddr, ']') |
40 if i > 0 { | 45 if i > 0 { |
41 » » » » tt.litAddr = tt.litAddr[:i] + "%" + ifi.Name + t
t.litAddr[i:] | 46 » » » » switch tt.addr.Zone { |
42 » » » » tt.addr.Zone = zoneToString(ifi.Index) | 47 » » » » case "name": |
| 48 » » » » » tt.litAddr = tt.litAddr[:i] + "%" + ifi.
Name + tt.litAddr[i:] |
| 49 » » » » » tt.addr.Zone = zoneToString(ifi.Index) |
| 50 » » » » case "index": |
| 51 » » » » » index := fmt.Sprintf("%v", ifi.Index) |
| 52 » » » » » tt.litAddr = tt.litAddr[:i] + "%" + inde
x + tt.litAddr[i:] |
| 53 » » » » » tt.addr.Zone = index |
| 54 » » » » } |
43 } | 55 } |
44 } | 56 } |
45 addr, err := ResolveUDPAddr(tt.net, tt.litAddr) | 57 addr, err := ResolveUDPAddr(tt.net, tt.litAddr) |
46 if err != tt.err { | 58 if err != tt.err { |
47 t.Fatalf("ResolveUDPAddr(%v, %v) failed: %v", tt.net, tt
.litAddr, err) | 59 t.Fatalf("ResolveUDPAddr(%v, %v) failed: %v", tt.net, tt
.litAddr, err) |
48 } | 60 } |
49 if !reflect.DeepEqual(addr, tt.addr) { | 61 if !reflect.DeepEqual(addr, tt.addr) { |
50 t.Fatalf("got %#v; expected %#v", addr, tt.addr) | 62 t.Fatalf("got %#v; expected %#v", addr, tt.addr) |
51 } | 63 } |
52 } | 64 } |
53 } | 65 } |
54 | 66 |
55 func TestWriteToUDP(t *testing.T) { | 67 func TestWriteToUDP(t *testing.T) { |
56 switch runtime.GOOS { | 68 switch runtime.GOOS { |
57 case "plan9": | 69 case "plan9": |
58 » » t.Logf("skipping test on %q", runtime.GOOS) | 70 » » t.Skipf("skipping test on %q", runtime.GOOS) |
59 » » return | |
60 } | 71 } |
61 | 72 |
62 l, err := ListenPacket("udp", "127.0.0.1:0") | 73 l, err := ListenPacket("udp", "127.0.0.1:0") |
63 if err != nil { | 74 if err != nil { |
64 t.Fatalf("Listen failed: %v", err) | 75 t.Fatalf("Listen failed: %v", err) |
65 } | 76 } |
66 defer l.Close() | 77 defer l.Close() |
67 | 78 |
68 testWriteToConn(t, l.LocalAddr().String()) | 79 testWriteToConn(t, l.LocalAddr().String()) |
69 testWriteToPacketConn(t, l.LocalAddr().String()) | 80 testWriteToPacketConn(t, l.LocalAddr().String()) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 } | 132 } |
122 | 133 |
123 _, err = c.WriteTo([]byte("Connection-less mode socket"), ra) | 134 _, err = c.WriteTo([]byte("Connection-less mode socket"), ra) |
124 if err != nil { | 135 if err != nil { |
125 t.Fatalf("WriteTo failed: %v", err) | 136 t.Fatalf("WriteTo failed: %v", err) |
126 } | 137 } |
127 | 138 |
128 _, err = c.(*UDPConn).Write([]byte("Connection-less mode socket")) | 139 _, err = c.(*UDPConn).Write([]byte("Connection-less mode socket")) |
129 if err == nil { | 140 if err == nil { |
130 t.Fatal("Write should fail") | 141 t.Fatal("Write should fail") |
131 } | |
132 } | |
133 | |
134 func TestIPv6LinkLocalAllNodesUDP(t *testing.T) { | |
135 switch runtime.GOOS { | |
136 case "darwin", "freebsd", "netbsd", "openbsd": | |
137 default: | |
138 t.Logf("skipping test on %q", runtime.GOOS) | |
139 return | |
140 } | |
141 if testing.Short() || !*testExternal { | |
142 t.Logf("skipping test to avoid external network") | |
143 return | |
144 } | |
145 if !supportsIPv6 { | |
146 t.Logf("skipping test; ipv6 is not supported") | |
147 return | |
148 } | |
149 ifi := loopbackInterface() | |
150 if ifi == nil { | |
151 t.Logf("skipping test; loopback interface not found") | |
152 } | |
153 | |
154 c, err := ListenPacket("udp6", "[::%"+ifi.Name+"]:0") | |
155 if err != nil { | |
156 t.Fatalf("ListenPacket failed: %v", err) | |
157 } | |
158 defer c.Close() | |
159 | |
160 _, port, err := SplitHostPort(c.LocalAddr().String()) | |
161 if err != nil { | |
162 t.Fatalf("SplitHostPort failed: %v", err) | |
163 } | |
164 ra, err := ResolveUDPAddr("udp6", "[ff02::1%"+ifi.Name+"]:"+port) | |
165 if err != nil { | |
166 t.Fatalf("ResolveUDPAddr failed: %v", err) | |
167 } | |
168 | |
169 if _, err := c.WriteTo([]byte("UDP FOR IPV6 LINKLOCAL TEST"), ra); err !
= nil { | |
170 t.Fatalf("WriteTo failed: %v", err) | |
171 } | |
172 rb := make([]byte, 64) | |
173 if _, _, err := c.ReadFrom(rb); err != nil { | |
174 t.Fatalf("ReadFrom failed: %v", err) | |
175 } | 142 } |
176 } | 143 } |
177 | 144 |
178 var udpConnLocalNameTests = []struct { | 145 var udpConnLocalNameTests = []struct { |
179 net string | 146 net string |
180 laddr *UDPAddr | 147 laddr *UDPAddr |
181 }{ | 148 }{ |
182 {"udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}}, | 149 {"udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}}, |
183 {"udp4", &UDPAddr{}}, | 150 {"udp4", &UDPAddr{}}, |
184 {"udp4", nil}, | 151 {"udp4", nil}, |
185 } | 152 } |
186 | 153 |
187 func TestUDPConnLocalName(t *testing.T) { | 154 func TestUDPConnLocalName(t *testing.T) { |
188 if testing.Short() || !*testExternal { | 155 if testing.Short() || !*testExternal { |
189 » » t.Logf("skipping test to avoid external network") | 156 » » t.Skip("skipping test to avoid external network") |
190 » » return | |
191 } | 157 } |
192 | 158 |
193 for _, tt := range udpConnLocalNameTests { | 159 for _, tt := range udpConnLocalNameTests { |
194 c, err := ListenUDP(tt.net, tt.laddr) | 160 c, err := ListenUDP(tt.net, tt.laddr) |
195 if err != nil { | 161 if err != nil { |
196 t.Errorf("ListenUDP failed: %v", err) | 162 t.Errorf("ListenUDP failed: %v", err) |
197 return | 163 return |
198 } | 164 } |
199 defer c.Close() | 165 defer c.Close() |
200 la := c.LocalAddr() | 166 la := c.LocalAddr() |
201 if a, ok := la.(*UDPAddr); !ok || a.Port == 0 { | 167 if a, ok := la.(*UDPAddr); !ok || a.Port == 0 { |
202 t.Errorf("got %v; expected a proper address with non-zer
o port number", la) | 168 t.Errorf("got %v; expected a proper address with non-zer
o port number", la) |
203 return | 169 return |
204 } | 170 } |
205 } | 171 } |
206 } | 172 } |
| 173 |
| 174 func TestIPv6LinkLocalUnicastUDP(t *testing.T) { |
| 175 if testing.Short() || !*testExternal { |
| 176 t.Skip("skipping test to avoid external network") |
| 177 } |
| 178 if !supportsIPv6 { |
| 179 t.Skip("ipv6 is not supported") |
| 180 } |
| 181 ifi := loopbackInterface() |
| 182 if ifi == nil { |
| 183 t.Skip("loopback interface not found") |
| 184 } |
| 185 laddr := ipv6LinkLocalUnicastAddr(ifi) |
| 186 if laddr == "" { |
| 187 t.Skip("ipv6 unicast address on loopback not found") |
| 188 } |
| 189 |
| 190 type test struct { |
| 191 net, addr string |
| 192 nameLookup bool |
| 193 } |
| 194 var tests = []test{ |
| 195 {"udp", "[" + laddr + "%" + ifi.Name + "]:0", false}, |
| 196 {"udp6", "[" + laddr + "%" + ifi.Name + "]:0", false}, |
| 197 } |
| 198 switch runtime.GOOS { |
| 199 case "darwin", "freebsd", "openbsd", "netbsd": |
| 200 tests = append(tests, []test{ |
| 201 {"udp", "[localhost%" + ifi.Name + "]:0", true}, |
| 202 {"udp6", "[localhost%" + ifi.Name + "]:0", true}, |
| 203 }...) |
| 204 case "linux": |
| 205 tests = append(tests, []test{ |
| 206 {"udp", "[ip6-localhost%" + ifi.Name + "]:0", true}, |
| 207 {"udp6", "[ip6-localhost%" + ifi.Name + "]:0", true}, |
| 208 }...) |
| 209 } |
| 210 for _, tt := range tests { |
| 211 c1, err := ListenPacket(tt.net, tt.addr) |
| 212 if err != nil { |
| 213 // It might return "LookupHost returned no |
| 214 // suitable address" error on some platforms. |
| 215 t.Logf("ListenPacket failed: %v", err) |
| 216 continue |
| 217 } |
| 218 defer c1.Close() |
| 219 if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup &&
la.Zone == "" { |
| 220 t.Fatalf("got %v; expected a proper address with zone id
entifier", la) |
| 221 } |
| 222 |
| 223 c2, err := Dial(tt.net, c1.LocalAddr().String()) |
| 224 if err != nil { |
| 225 t.Fatalf("Dial failed: %v", err) |
| 226 } |
| 227 defer c2.Close() |
| 228 if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup &&
la.Zone == "" { |
| 229 t.Fatalf("got %v; expected a proper address with zone id
entifier", la) |
| 230 } |
| 231 if ra, ok := c2.RemoteAddr().(*UDPAddr); !ok || !tt.nameLookup &
& ra.Zone == "" { |
| 232 t.Fatalf("got %v; expected a proper address with zone id
entifier", ra) |
| 233 } |
| 234 |
| 235 if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); e
rr != nil { |
| 236 t.Fatalf("Conn.Write failed: %v", err) |
| 237 } |
| 238 b := make([]byte, 32) |
| 239 if _, from, err := c1.ReadFrom(b); err != nil { |
| 240 t.Fatalf("PacketConn.ReadFrom failed: %v", err) |
| 241 } else { |
| 242 if ra, ok := from.(*UDPAddr); !ok || !tt.nameLookup && r
a.Zone == "" { |
| 243 t.Fatalf("got %v; expected a proper address with
zone identifier", ra) |
| 244 } |
| 245 } |
| 246 } |
| 247 } |
LEFT | RIGHT |