diff options
author | Mikio Hara <mikioh.mikioh@gmail.com> | 2015-05-14 17:00:25 +0900 |
---|---|---|
committer | Mikio Hara <mikioh.mikioh@gmail.com> | 2015-05-22 23:47:27 +0000 |
commit | 621fff363a1d9ad7fdd0bfa9d80a42881267deb4 (patch) | |
tree | 4a33f54712a25cd4cbc8c1e1799275e8b421cc5d | |
parent | ad9eb3904af97b912b9a242efb203c5c6782e72a (diff) | |
download | net-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.go | 141 |
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) + } } |