aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikio Hara <mikioh.mikioh@gmail.com>2015-05-14 17:00:25 +0900
committerMikio Hara <mikioh.mikioh@gmail.com>2015-05-22 23:47:27 +0000
commit621fff363a1d9ad7fdd0bfa9d80a42881267deb4 (patch)
tree4a33f54712a25cd4cbc8c1e1799275e8b421cc5d
parentad9eb3904af97b912b9a242efb203c5c6782e72a (diff)
downloadnet-621fff363a1d9ad7fdd0bfa9d80a42881267deb4.tar.gz
icmp: more coverage to ping test
This change splits the existing ping test into non-privileged and privileged tests to cover IPConn full stack test on behalf of the standard library. Updates golang/go#10730. Change-Id: I5d2e00c0b42b857045414eb8e0efca393967742e Reviewed-on: https://go-review.googlesource.com/10090 Reviewed-by: Ian Lance Taylor <iant@golang.org>
-rw-r--r--icmp/ping_test.go141
1 files changed, 87 insertions, 54 deletions
diff --git a/icmp/ping_test.go b/icmp/ping_test.go
index 440aedd..be7d537 100644
--- a/icmp/ping_test.go
+++ b/icmp/ping_test.go
@@ -6,10 +6,12 @@ package icmp_test
import (
"errors"
+ "fmt"
"net"
"os"
"runtime"
"testing"
+ "time"
"golang.org/x/net/icmp"
"golang.org/x/net/internal/iana"
@@ -49,21 +51,21 @@ func googleAddr(c *icmp.PacketConn, protocol int) (net.Addr, error) {
return nil, errors.New("no A or AAAA record")
}
-var pingGoogleTests = []struct {
+type pingTest struct {
network, address string
protocol int
mtype icmp.Type
-}{
+}
+
+var nonPrivilegedPingTests = []pingTest{
{"udp4", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho},
- {"ip4:icmp", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho},
{"udp6", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest},
- {"ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest},
}
-func TestPingGoogle(t *testing.T) {
+func TestNonPrivilegedPing(t *testing.T) {
if testing.Short() {
- t.Skip("to avoid external network")
+ t.Skip("avoid external network")
}
switch runtime.GOOS {
case "darwin":
@@ -73,61 +75,92 @@ func TestPingGoogle(t *testing.T) {
t.Skipf("not supported on %s", runtime.GOOS)
}
- m, ok := nettest.SupportsRawIPSocket()
- for i, tt := range pingGoogleTests {
- if tt.network[:2] == "ip" && !ok {
- t.Log(m)
- continue
- }
- c, err := icmp.ListenPacket(tt.network, tt.address)
- if err != nil {
+ for i, tt := range nonPrivilegedPingTests {
+ if err := doPing(tt, i); err != nil {
t.Error(err)
- continue
}
- defer c.Close()
+ }
+}
- dst, err := googleAddr(c, tt.protocol)
- if err != nil {
- t.Error(err)
- continue
- }
+var privilegedPingTests = []pingTest{
+ {"ip4:icmp", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho},
- wm := icmp.Message{
- Type: tt.mtype, Code: 0,
- Body: &icmp.Echo{
- ID: os.Getpid() & 0xffff, Seq: 1 << uint(i),
- Data: []byte("HELLO-R-U-THERE"),
- },
- }
- wb, err := wm.Marshal(nil)
- if err != nil {
- t.Error(err)
- continue
- }
- if n, err := c.WriteTo(wb, dst); err != nil {
- t.Error(err, dst)
- continue
- } else if n != len(wb) {
- t.Errorf("got %v; want %v", n, len(wb))
- continue
- }
+ {"ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest},
+}
- rb := make([]byte, 1500)
- n, peer, err := c.ReadFrom(rb)
- if err != nil {
- t.Error(err)
- continue
- }
- rm, err := icmp.ParseMessage(tt.protocol, rb[:n])
- if err != nil {
+func TestPrivilegedPing(t *testing.T) {
+ if testing.Short() {
+ t.Skip("avoid external network")
+ }
+ if m, ok := nettest.SupportsRawIPSocket(); !ok {
+ t.Skip(m)
+ }
+
+ for i, tt := range privilegedPingTests {
+ if err := doPing(tt, i); err != nil {
t.Error(err)
- continue
}
- switch rm.Type {
- case ipv4.ICMPTypeEchoReply, ipv6.ICMPTypeEchoReply:
- t.Logf("got reflection from %v", peer)
- default:
- t.Errorf("got %+v; want echo reply", rm)
+ }
+}
+
+func doPing(tt pingTest, seq int) error {
+ c, err := icmp.ListenPacket(tt.network, tt.address)
+ if err != nil {
+ return err
+ }
+ defer c.Close()
+
+ dst, err := googleAddr(c, tt.protocol)
+ if err != nil {
+ return err
+ }
+
+ if tt.protocol == iana.ProtocolIPv6ICMP {
+ var f ipv6.ICMPFilter
+ f.SetAll(true)
+ f.Accept(ipv6.ICMPTypeDestinationUnreachable)
+ f.Accept(ipv6.ICMPTypePacketTooBig)
+ f.Accept(ipv6.ICMPTypeTimeExceeded)
+ f.Accept(ipv6.ICMPTypeParameterProblem)
+ f.Accept(ipv6.ICMPTypeEchoReply)
+ if err := c.IPv6PacketConn().SetICMPFilter(&f); err != nil {
+ return err
}
}
+
+ wm := icmp.Message{
+ Type: tt.mtype, Code: 0,
+ Body: &icmp.Echo{
+ ID: os.Getpid() & 0xffff, Seq: 1 << uint(seq),
+ Data: []byte("HELLO-R-U-THERE"),
+ },
+ }
+ wb, err := wm.Marshal(nil)
+ if err != nil {
+ return err
+ }
+ if n, err := c.WriteTo(wb, dst); err != nil {
+ return err
+ } else if n != len(wb) {
+ return fmt.Errorf("got %v; want %v", n, len(wb))
+ }
+
+ rb := make([]byte, 1500)
+ if err := c.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
+ return err
+ }
+ n, peer, err := c.ReadFrom(rb)
+ if err != nil {
+ return err
+ }
+ rm, err := icmp.ParseMessage(tt.protocol, rb[:n])
+ if err != nil {
+ return err
+ }
+ switch rm.Type {
+ case ipv4.ICMPTypeEchoReply, ipv6.ICMPTypeEchoReply:
+ return nil
+ default:
+ return fmt.Errorf("got %+v from %v; want echo reply", rm, peer)
+ }
}