diff --git a/ipv6/example_test.go b/ipv6/example_test.go index d0c9695a..2f7540fc 100644 --- a/ipv6/example_test.go +++ b/ipv6/example_test.go @@ -122,8 +122,8 @@ func ExamplePacketConn_tracingIPPacketRoute() { } var f ipv6.ICMPFilter f.SetAll(true) - f.Set(ipv6.ICMPTypeTimeExceeded, false) - f.Set(ipv6.ICMPTypeEchoReply, false) + f.Accept(ipv6.ICMPTypeTimeExceeded) + f.Accept(ipv6.ICMPTypeEchoReply) if err := p.SetICMPFilter(&f); err != nil { log.Fatal(err) } diff --git a/ipv6/icmp.go b/ipv6/icmp.go index 9a6dc2d4..a2de65a0 100644 --- a/ipv6/icmp.go +++ b/ipv6/icmp.go @@ -4,11 +4,7 @@ package ipv6 -import ( - "sync" - - "golang.org/x/net/internal/iana" -) +import "golang.org/x/net/internal/iana" // An ICMPType represents a type of ICMP message. type ICMPType int @@ -27,30 +23,35 @@ func (typ ICMPType) Protocol() int { } // An ICMPFilter represents an ICMP message filter for incoming -// packets. +// packets. The filter belongs to a packet delivery path on a host and +// it cannot interact with forwarding packets or tunnel-outer packets. +// +// Note: RFC 2460 defines a reasonable role model. A node means a +// device that implements IP. A router means a node that forwards IP +// packets not explicitly addressed to itself, and a host means a node +// that is not a router. type ICMPFilter struct { - mu sync.RWMutex sysICMPv6Filter } -// Set sets the ICMP type and filter action to the filter. -func (f *ICMPFilter) Set(typ ICMPType, block bool) { - f.mu.Lock() - f.set(typ, block) - f.mu.Unlock() +// Accept accepts incoming ICMP packets including the type field value +// typ. +func (f *ICMPFilter) Accept(typ ICMPType) { + f.accept(typ) +} + +// Block blocks incoming ICMP packets including the type field value +// typ. +func (f *ICMPFilter) Block(typ ICMPType) { + f.block(typ) } // SetAll sets the filter action to the filter. func (f *ICMPFilter) SetAll(block bool) { - f.mu.Lock() f.setAll(block) - f.mu.Unlock() } // WillBlock reports whether the ICMP type will be blocked. func (f *ICMPFilter) WillBlock(typ ICMPType) bool { - f.mu.RLock() - ok := f.willBlock(typ) - f.mu.RUnlock() - return ok + return f.willBlock(typ) } diff --git a/ipv6/icmp_bsd.go b/ipv6/icmp_bsd.go index f6f7d787..30e3ce42 100644 --- a/ipv6/icmp_bsd.go +++ b/ipv6/icmp_bsd.go @@ -6,12 +6,12 @@ package ipv6 -func (f *sysICMPv6Filter) set(typ ICMPType, block bool) { - if block { - f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31) - } else { - f.Filt[typ>>5] |= 1 << (uint32(typ) & 31) - } +func (f *sysICMPv6Filter) accept(typ ICMPType) { + f.Filt[typ>>5] |= 1 << (uint32(typ) & 31) +} + +func (f *sysICMPv6Filter) block(typ ICMPType) { + f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31) } func (f *sysICMPv6Filter) setAll(block bool) { diff --git a/ipv6/icmp_linux.go b/ipv6/icmp_linux.go index c04e585d..a67ecf69 100644 --- a/ipv6/icmp_linux.go +++ b/ipv6/icmp_linux.go @@ -4,12 +4,12 @@ package ipv6 -func (f *sysICMPv6Filter) set(typ ICMPType, block bool) { - if block { - f.Data[typ>>5] |= 1 << (uint32(typ) & 31) - } else { - f.Data[typ>>5] &^= 1 << (uint32(typ) & 31) - } +func (f *sysICMPv6Filter) accept(typ ICMPType) { + f.Data[typ>>5] &^= 1 << (uint32(typ) & 31) +} + +func (f *sysICMPv6Filter) block(typ ICMPType) { + f.Data[typ>>5] |= 1 << (uint32(typ) & 31) } func (f *sysICMPv6Filter) setAll(block bool) { diff --git a/ipv6/icmp_solaris.go b/ipv6/icmp_solaris.go index b5efef04..a942f354 100644 --- a/ipv6/icmp_solaris.go +++ b/ipv6/icmp_solaris.go @@ -6,7 +6,11 @@ package ipv6 -func (f *sysICMPv6Filter) set(typ ICMPType, block bool) { +func (f *sysICMPv6Filter) accept(typ ICMPType) { + // TODO(mikio): implement this +} + +func (f *sysICMPv6Filter) block(typ ICMPType) { // TODO(mikio): implement this } diff --git a/ipv6/icmp_stub.go b/ipv6/icmp_stub.go index 58b6a049..c1263eca 100644 --- a/ipv6/icmp_stub.go +++ b/ipv6/icmp_stub.go @@ -9,7 +9,10 @@ package ipv6 type sysICMPv6Filter struct { } -func (f *sysICMPv6Filter) set(typ ICMPType, block bool) { +func (f *sysICMPv6Filter) accept(typ ICMPType) { +} + +func (f *sysICMPv6Filter) block(typ ICMPType) { } func (f *sysICMPv6Filter) setAll(block bool) { diff --git a/ipv6/icmp_test.go b/ipv6/icmp_test.go index 6ca2c16f..76e02dc8 100644 --- a/ipv6/icmp_test.go +++ b/ipv6/icmp_test.go @@ -9,7 +9,6 @@ import ( "os" "reflect" "runtime" - "sync" "testing" "golang.org/x/net/ipv6" @@ -42,27 +41,21 @@ func TestICMPFilter(t *testing.T) { var f ipv6.ICMPFilter for _, toggle := range []bool{false, true} { f.SetAll(toggle) - var wg sync.WaitGroup for _, typ := range []ipv6.ICMPType{ ipv6.ICMPTypeDestinationUnreachable, ipv6.ICMPTypeEchoReply, ipv6.ICMPTypeNeighborSolicitation, ipv6.ICMPTypeDuplicateAddressConfirmation, } { - wg.Add(1) - go func(typ ipv6.ICMPType) { - defer wg.Done() - f.Set(typ, false) - if f.WillBlock(typ) { - t.Errorf("ipv6.ICMPFilter.Set(%v, false) failed", typ) - } - f.Set(typ, true) - if !f.WillBlock(typ) { - t.Errorf("ipv6.ICMPFilter.Set(%v, true) failed", typ) - } - }(typ) + f.Accept(typ) + if f.WillBlock(typ) { + t.Errorf("ipv6.ICMPFilter.Set(%v, false) failed", typ) + } + f.Block(typ) + if !f.WillBlock(typ) { + t.Errorf("ipv6.ICMPFilter.Set(%v, true) failed", typ) + } } - wg.Wait() } } @@ -88,8 +81,8 @@ func TestSetICMPFilter(t *testing.T) { var f ipv6.ICMPFilter f.SetAll(true) - f.Set(ipv6.ICMPTypeEchoRequest, false) - f.Set(ipv6.ICMPTypeEchoReply, false) + f.Accept(ipv6.ICMPTypeEchoRequest) + f.Accept(ipv6.ICMPTypeEchoReply) if err := p.SetICMPFilter(&f); err != nil { t.Fatal(err) } diff --git a/ipv6/icmp_windows.go b/ipv6/icmp_windows.go index 510c0d42..9dcfb810 100644 --- a/ipv6/icmp_windows.go +++ b/ipv6/icmp_windows.go @@ -8,7 +8,11 @@ type sysICMPv6Filter struct { // TODO(mikio): implement this } -func (f *sysICMPv6Filter) set(typ ICMPType, block bool) { +func (f *sysICMPv6Filter) accept(typ ICMPType) { + // TODO(mikio): implement this +} + +func (f *sysICMPv6Filter) block(typ ICMPType) { // TODO(mikio): implement this } diff --git a/ipv6/multicast_test.go b/ipv6/multicast_test.go index 60dea5da..768f404c 100644 --- a/ipv6/multicast_test.go +++ b/ipv6/multicast_test.go @@ -197,7 +197,7 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) { var f ipv6.ICMPFilter f.SetAll(true) - f.Set(ipv6.ICMPTypeEchoReply, false) + f.Accept(ipv6.ICMPTypeEchoReply) if err := p.SetICMPFilter(&f); err != nil { t.Fatal(err) } diff --git a/ipv6/unicast_test.go b/ipv6/unicast_test.go index c4699c18..6394965a 100644 --- a/ipv6/unicast_test.go +++ b/ipv6/unicast_test.go @@ -119,7 +119,7 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) { var f ipv6.ICMPFilter f.SetAll(true) - f.Set(ipv6.ICMPTypeEchoReply, false) + f.Accept(ipv6.ICMPTypeEchoReply) if err := p.SetICMPFilter(&f); err != nil { t.Fatal(err) }