LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 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 "bytes" | 8 "bytes" |
9 "errors" | 9 "errors" |
10 "flag" | |
11 "fmt" | 10 "fmt" |
12 "os" | 11 "os" |
13 "reflect" | 12 "reflect" |
14 "runtime" | 13 "runtime" |
15 "testing" | 14 "testing" |
16 "time" | 15 "time" |
17 ) | 16 ) |
18 | 17 |
19 var testRawIP = flag.Bool("rawip", false, "run test requires raw IP facility acc
ess privilege") | |
20 | |
21 type resolveIPAddrTest struct { | 18 type resolveIPAddrTest struct { |
22 net string | 19 net string |
23 litAddr string | 20 litAddr string |
24 addr *IPAddr | 21 addr *IPAddr |
25 err error | 22 err error |
26 } | 23 } |
27 | 24 |
28 var resolveIPAddrTests = []resolveIPAddrTest{ | 25 var resolveIPAddrTests = []resolveIPAddrTest{ |
29 {"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, | 26 {"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, |
30 {"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, | 27 {"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, |
31 {"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, | 28 {"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, |
32 | 29 |
33 {"ip", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, | 30 {"ip", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, |
34 {"ip6", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, | 31 {"ip6", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, |
35 {"ip6:ipv6-icmp", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, | 32 {"ip6:ipv6-icmp", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, |
| 33 {"ip6:IPv6-ICMP", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, |
36 | 34 |
37 {"ip", "::1%en0", &IPAddr{IP: ParseIP("::1"), Zone: "en0"}, nil}, | 35 {"ip", "::1%en0", &IPAddr{IP: ParseIP("::1"), Zone: "en0"}, nil}, |
38 {"ip6", "::1%911", &IPAddr{IP: ParseIP("::1"), Zone: "911"}, nil}, | 36 {"ip6", "::1%911", &IPAddr{IP: ParseIP("::1"), Zone: "911"}, nil}, |
39 | 37 |
40 {"", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, // Go 1.0 behav
ior | 38 {"", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, // Go 1.0 behav
ior |
41 {"", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, // Go 1.0 behav
ior | 39 {"", "::1", &IPAddr{IP: ParseIP("::1")}, nil}, // Go 1.0 behav
ior |
42 | 40 |
43 {"l2tp", "127.0.0.1", nil, UnknownNetworkError("l2tp")}, | 41 {"l2tp", "127.0.0.1", nil, UnknownNetworkError("l2tp")}, |
44 {"l2tp:gre", "127.0.0.1", nil, UnknownNetworkError("l2tp:gre")}, | 42 {"l2tp:gre", "127.0.0.1", nil, UnknownNetworkError("l2tp:gre")}, |
45 {"tcp", "1.2.3.4:123", nil, UnknownNetworkError("tcp")}, | 43 {"tcp", "1.2.3.4:123", nil, UnknownNetworkError("tcp")}, |
46 } | 44 } |
47 | 45 |
48 func init() { | 46 func init() { |
49 if ifi := loopbackInterface(); ifi != nil { | 47 if ifi := loopbackInterface(); ifi != nil { |
50 index := fmt.Sprintf("%v", ifi.Index) | 48 index := fmt.Sprintf("%v", ifi.Index) |
51 resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrT
est{ | 49 resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrT
est{ |
52 {"ip6", "fe80::1%" + ifi.Name, &IPAddr{IP: ParseIP("fe80
::1"), Zone: zoneToString(ifi.Index)}, nil}, | 50 {"ip6", "fe80::1%" + ifi.Name, &IPAddr{IP: ParseIP("fe80
::1"), Zone: zoneToString(ifi.Index)}, nil}, |
53 {"ip6", "fe80::1%" + index, &IPAddr{IP: ParseIP("fe80::1
"), Zone: index}, nil}, | 51 {"ip6", "fe80::1%" + index, &IPAddr{IP: ParseIP("fe80::1
"), Zone: index}, nil}, |
54 }...) | 52 }...) |
55 } | 53 } |
56 } | 54 } |
57 | 55 |
58 func TestResolveIPAddr(t *testing.T) { | 56 func TestResolveIPAddr(t *testing.T) { |
59 for _, tt := range resolveIPAddrTests { | 57 for _, tt := range resolveIPAddrTests { |
60 addr, err := ResolveIPAddr(tt.net, tt.litAddr) | 58 addr, err := ResolveIPAddr(tt.net, tt.litAddr) |
61 if err != tt.err { | 59 if err != tt.err { |
62 » » » condFatalf(t, "ResolveIPAddr(%v, %v) failed: %v", tt.net
, tt.litAddr, err) | 60 » » » t.Fatalf("ResolveIPAddr(%v, %v) failed: %v", tt.net, tt.
litAddr, err) |
63 } else if !reflect.DeepEqual(addr, tt.addr) { | 61 } else if !reflect.DeepEqual(addr, tt.addr) { |
64 t.Fatalf("got %#v; expected %#v", addr, tt.addr) | 62 t.Fatalf("got %#v; expected %#v", addr, tt.addr) |
65 } | 63 } |
66 } | 64 } |
67 } | 65 } |
68 | 66 |
69 var icmpEchoTests = []struct { | 67 var icmpEchoTests = []struct { |
70 net string | 68 net string |
71 laddr string | 69 laddr string |
72 raddr string | 70 raddr string |
73 }{ | 71 }{ |
74 {"ip4:icmp", "0.0.0.0", "127.0.0.1"}, | 72 {"ip4:icmp", "0.0.0.0", "127.0.0.1"}, |
75 {"ip6:ipv6-icmp", "::", "::1"}, | 73 {"ip6:ipv6-icmp", "::", "::1"}, |
76 } | 74 } |
77 | 75 |
78 func TestConnICMPEcho(t *testing.T) { | 76 func TestConnICMPEcho(t *testing.T) { |
79 switch runtime.GOOS { | 77 switch runtime.GOOS { |
80 case "plan9": | 78 case "plan9": |
81 t.Skipf("skipping test on %q", runtime.GOOS) | 79 t.Skipf("skipping test on %q", runtime.GOOS) |
| 80 case "windows": |
82 default: | 81 default: |
83 » » if !*testRawIP { | 82 » » if os.Getuid() != 0 { |
84 » » » t.Skip("test disabled; use -rawip to enable") | 83 » » » t.Skip("skipping test; must be root") |
85 } | 84 } |
86 } | 85 } |
87 | 86 |
88 for i, tt := range icmpEchoTests { | 87 for i, tt := range icmpEchoTests { |
89 net, _, err := parseNetwork(tt.net) | 88 net, _, err := parseNetwork(tt.net) |
90 if err != nil { | 89 if err != nil { |
91 t.Fatalf("parseNetwork failed: %v", err) | 90 t.Fatalf("parseNetwork failed: %v", err) |
92 } | 91 } |
93 if net == "ip6" && !supportsIPv6 { | 92 if net == "ip6" && !supportsIPv6 { |
94 continue | 93 continue |
95 } | 94 } |
96 | 95 |
97 c, err := Dial(tt.net, tt.raddr) | 96 c, err := Dial(tt.net, tt.raddr) |
98 if err != nil { | 97 if err != nil { |
99 t.Fatalf("Dial failed: %v", err) | 98 t.Fatalf("Dial failed: %v", err) |
100 } | 99 } |
101 c.SetDeadline(time.Now().Add(100 * time.Millisecond)) | 100 c.SetDeadline(time.Now().Add(100 * time.Millisecond)) |
102 defer c.Close() | 101 defer c.Close() |
103 | 102 |
104 typ := icmpv4EchoRequest | 103 typ := icmpv4EchoRequest |
105 if net == "ip6" { | 104 if net == "ip6" { |
106 typ = icmpv6EchoRequest | 105 typ = icmpv6EchoRequest |
107 } | 106 } |
108 xid, xseq := os.Getpid()&0xffff, i+1 | 107 xid, xseq := os.Getpid()&0xffff, i+1 |
109 » » b, err := (&icmpMessage{ | 108 » » wb, err := (&icmpMessage{ |
110 Type: typ, Code: 0, | 109 Type: typ, Code: 0, |
111 Body: &icmpEcho{ | 110 Body: &icmpEcho{ |
112 ID: xid, Seq: xseq, | 111 ID: xid, Seq: xseq, |
113 Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"
), 3), | 112 Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"
), 3), |
114 }, | 113 }, |
115 }).Marshal() | 114 }).Marshal() |
116 if err != nil { | 115 if err != nil { |
117 t.Fatalf("icmpMessage.Marshal failed: %v", err) | 116 t.Fatalf("icmpMessage.Marshal failed: %v", err) |
118 } | 117 } |
119 » » if _, err := c.Write(b); err != nil { | 118 » » if _, err := c.Write(wb); err != nil { |
120 t.Fatalf("Conn.Write failed: %v", err) | 119 t.Fatalf("Conn.Write failed: %v", err) |
121 } | 120 } |
122 var m *icmpMessage | 121 var m *icmpMessage |
| 122 rb := make([]byte, 20+len(wb)) |
123 for { | 123 for { |
124 » » » if _, err := c.Read(b); err != nil { | 124 » » » if _, err := c.Read(rb); err != nil { |
125 t.Fatalf("Conn.Read failed: %v", err) | 125 t.Fatalf("Conn.Read failed: %v", err) |
126 } | 126 } |
127 if net == "ip4" { | 127 if net == "ip4" { |
128 » » » » b = ipv4Payload(b) | 128 » » » » rb = ipv4Payload(rb) |
129 » » » } | 129 » » » } |
130 » » » if m, err = parseICMPMessage(b); err != nil { | 130 » » » if m, err = parseICMPMessage(rb); err != nil { |
131 t.Fatalf("parseICMPMessage failed: %v", err) | 131 t.Fatalf("parseICMPMessage failed: %v", err) |
132 } | 132 } |
133 switch m.Type { | 133 switch m.Type { |
134 case icmpv4EchoRequest, icmpv6EchoRequest: | 134 case icmpv4EchoRequest, icmpv6EchoRequest: |
135 continue | 135 continue |
136 } | 136 } |
137 break | 137 break |
138 } | 138 } |
139 switch p := m.Body.(type) { | 139 switch p := m.Body.(type) { |
140 case *icmpEcho: | 140 case *icmpEcho: |
141 if p.ID != xid || p.Seq != xseq { | 141 if p.ID != xid || p.Seq != xseq { |
142 t.Fatalf("got id=%v, seqnum=%v; expected id=%v,
seqnum=%v", p.ID, p.Seq, xid, xseq) | 142 t.Fatalf("got id=%v, seqnum=%v; expected id=%v,
seqnum=%v", p.ID, p.Seq, xid, xseq) |
143 } | 143 } |
144 default: | 144 default: |
145 t.Fatalf("got type=%v, code=%v; expected type=%v, code=%
v", m.Type, m.Code, typ, 0) | 145 t.Fatalf("got type=%v, code=%v; expected type=%v, code=%
v", m.Type, m.Code, typ, 0) |
146 } | 146 } |
147 } | 147 } |
148 } | 148 } |
149 | 149 |
150 func TestPacketConnICMPEcho(t *testing.T) { | 150 func TestPacketConnICMPEcho(t *testing.T) { |
151 switch runtime.GOOS { | 151 switch runtime.GOOS { |
152 case "plan9": | 152 case "plan9": |
153 t.Skipf("skipping test on %q", runtime.GOOS) | 153 t.Skipf("skipping test on %q", runtime.GOOS) |
| 154 case "windows": |
154 default: | 155 default: |
155 » » if !*testRawIP { | 156 » » if os.Getuid() != 0 { |
156 » » » t.Skip("test disabled; use -rawip to enable") | 157 » » » t.Skip("skipping test; must be root") |
157 } | 158 } |
158 } | 159 } |
159 | 160 |
160 for i, tt := range icmpEchoTests { | 161 for i, tt := range icmpEchoTests { |
161 net, _, err := parseNetwork(tt.net) | 162 net, _, err := parseNetwork(tt.net) |
162 if err != nil { | 163 if err != nil { |
163 t.Fatalf("parseNetwork failed: %v", err) | 164 t.Fatalf("parseNetwork failed: %v", err) |
164 } | 165 } |
165 if net == "ip6" && !supportsIPv6 { | 166 if net == "ip6" && !supportsIPv6 { |
166 continue | 167 continue |
167 } | 168 } |
168 | 169 |
169 c, err := ListenPacket(tt.net, tt.laddr) | 170 c, err := ListenPacket(tt.net, tt.laddr) |
170 if err != nil { | 171 if err != nil { |
171 t.Fatalf("ListenPacket failed: %v", err) | 172 t.Fatalf("ListenPacket failed: %v", err) |
172 } | 173 } |
173 c.SetDeadline(time.Now().Add(100 * time.Millisecond)) | 174 c.SetDeadline(time.Now().Add(100 * time.Millisecond)) |
174 defer c.Close() | 175 defer c.Close() |
175 | 176 |
176 ra, err := ResolveIPAddr(tt.net, tt.raddr) | 177 ra, err := ResolveIPAddr(tt.net, tt.raddr) |
177 if err != nil { | 178 if err != nil { |
178 t.Fatalf("ResolveIPAddr failed: %v", err) | 179 t.Fatalf("ResolveIPAddr failed: %v", err) |
179 } | 180 } |
180 typ := icmpv4EchoRequest | 181 typ := icmpv4EchoRequest |
181 if net == "ip6" { | 182 if net == "ip6" { |
182 typ = icmpv6EchoRequest | 183 typ = icmpv6EchoRequest |
183 } | 184 } |
184 xid, xseq := os.Getpid()&0xffff, i+1 | 185 xid, xseq := os.Getpid()&0xffff, i+1 |
185 » » b, err := (&icmpMessage{ | 186 » » wb, err := (&icmpMessage{ |
186 Type: typ, Code: 0, | 187 Type: typ, Code: 0, |
187 Body: &icmpEcho{ | 188 Body: &icmpEcho{ |
188 ID: xid, Seq: xseq, | 189 ID: xid, Seq: xseq, |
189 Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"
), 3), | 190 Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"
), 3), |
190 }, | 191 }, |
191 }).Marshal() | 192 }).Marshal() |
192 if err != nil { | 193 if err != nil { |
193 t.Fatalf("icmpMessage.Marshal failed: %v", err) | 194 t.Fatalf("icmpMessage.Marshal failed: %v", err) |
194 } | 195 } |
195 » » if _, err := c.WriteTo(b, ra); err != nil { | 196 » » if _, err := c.WriteTo(wb, ra); err != nil { |
196 t.Fatalf("PacketConn.WriteTo failed: %v", err) | 197 t.Fatalf("PacketConn.WriteTo failed: %v", err) |
197 } | 198 } |
198 var m *icmpMessage | 199 var m *icmpMessage |
| 200 rb := make([]byte, 20+len(wb)) |
199 for { | 201 for { |
200 » » » if _, _, err := c.ReadFrom(b); err != nil { | 202 » » » if _, _, err := c.ReadFrom(rb); err != nil { |
201 t.Fatalf("PacketConn.ReadFrom failed: %v", err) | 203 t.Fatalf("PacketConn.ReadFrom failed: %v", err) |
202 } | 204 } |
203 // TODO: fix issue 3944 | 205 // TODO: fix issue 3944 |
204 //if net == "ip4" { | 206 //if net == "ip4" { |
205 » » » //» b = ipv4Payload(b) | 207 » » » //» rb = ipv4Payload(rb) |
206 //} | 208 //} |
207 » » » if m, err = parseICMPMessage(b); err != nil { | 209 » » » if m, err = parseICMPMessage(rb); err != nil { |
208 t.Fatalf("parseICMPMessage failed: %v", err) | 210 t.Fatalf("parseICMPMessage failed: %v", err) |
209 } | 211 } |
210 switch m.Type { | 212 switch m.Type { |
211 case icmpv4EchoRequest, icmpv6EchoRequest: | 213 case icmpv4EchoRequest, icmpv6EchoRequest: |
212 continue | 214 continue |
213 } | 215 } |
214 break | 216 break |
215 } | 217 } |
216 switch p := m.Body.(type) { | 218 switch p := m.Body.(type) { |
217 case *icmpEcho: | 219 case *icmpEcho: |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 net string | 347 net string |
346 laddr *IPAddr | 348 laddr *IPAddr |
347 }{ | 349 }{ |
348 {"ip4:icmp", &IPAddr{IP: IPv4(127, 0, 0, 1)}}, | 350 {"ip4:icmp", &IPAddr{IP: IPv4(127, 0, 0, 1)}}, |
349 {"ip4:icmp", &IPAddr{}}, | 351 {"ip4:icmp", &IPAddr{}}, |
350 {"ip4:icmp", nil}, | 352 {"ip4:icmp", nil}, |
351 } | 353 } |
352 | 354 |
353 func TestIPConnLocalName(t *testing.T) { | 355 func TestIPConnLocalName(t *testing.T) { |
354 switch runtime.GOOS { | 356 switch runtime.GOOS { |
355 » case "plan9": | 357 » case "plan9", "windows": |
356 t.Skipf("skipping test on %q", runtime.GOOS) | 358 t.Skipf("skipping test on %q", runtime.GOOS) |
357 default: | 359 default: |
358 » » if !*testRawIP { | 360 » » if os.Getuid() != 0 { |
359 » » » t.Skip("test disabled; use -rawip to enable") | 361 » » » t.Skip("skipping test; must be root") |
360 } | 362 } |
361 } | 363 } |
362 | 364 |
363 for _, tt := range ipConnLocalNameTests { | 365 for _, tt := range ipConnLocalNameTests { |
364 c, err := ListenIP(tt.net, tt.laddr) | 366 c, err := ListenIP(tt.net, tt.laddr) |
365 if err != nil { | 367 if err != nil { |
366 t.Fatalf("ListenIP failed: %v", err) | 368 t.Fatalf("ListenIP failed: %v", err) |
367 } | 369 } |
368 defer c.Close() | 370 defer c.Close() |
369 if la := c.LocalAddr(); la == nil { | 371 if la := c.LocalAddr(); la == nil { |
370 t.Fatal("IPConn.LocalAddr failed") | 372 t.Fatal("IPConn.LocalAddr failed") |
371 } | 373 } |
372 } | 374 } |
373 } | 375 } |
374 | 376 |
375 func TestIPConnRemoteName(t *testing.T) { | 377 func TestIPConnRemoteName(t *testing.T) { |
376 switch runtime.GOOS { | 378 switch runtime.GOOS { |
377 » case "plan9": | 379 » case "plan9", "windows": |
378 t.Skipf("skipping test on %q", runtime.GOOS) | 380 t.Skipf("skipping test on %q", runtime.GOOS) |
379 default: | 381 default: |
380 » » if !*testRawIP { | 382 » » if os.Getuid() != 0 { |
381 » » » t.Skip("test disabled; use -rawip to enable") | 383 » » » t.Skip("skipping test; must be root") |
382 } | 384 } |
383 } | 385 } |
384 | 386 |
385 raddr := &IPAddr{IP: IPv4(127, 0, 0, 10).To4()} | 387 raddr := &IPAddr{IP: IPv4(127, 0, 0, 10).To4()} |
386 c, err := DialIP("ip:tcp", &IPAddr{IP: IPv4(127, 0, 0, 1)}, raddr) | 388 c, err := DialIP("ip:tcp", &IPAddr{IP: IPv4(127, 0, 0, 1)}, raddr) |
387 if err != nil { | 389 if err != nil { |
388 t.Fatalf("DialIP failed: %v", err) | 390 t.Fatalf("DialIP failed: %v", err) |
389 } | 391 } |
390 defer c.Close() | 392 defer c.Close() |
391 if !reflect.DeepEqual(raddr, c.RemoteAddr()) { | 393 if !reflect.DeepEqual(raddr, c.RemoteAddr()) { |
392 t.Fatalf("got %#v, expected %#v", c.RemoteAddr(), raddr) | 394 t.Fatalf("got %#v, expected %#v", c.RemoteAddr(), raddr) |
393 } | 395 } |
394 } | 396 } |
LEFT | RIGHT |