Skip to content
This repository has been archived by the owner on May 14, 2020. It is now read-only.

deprecate this package; moved to multiformats/go-multiaddr. #23

Merged
merged 2 commits into from
May 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## ⚠️ DEPRECATED: Filters have been migrated to [multiformats/go-multiaddr](https://github.com/multiformats/go-multiaddr).

go-maddr-filter
==================

Expand Down
186 changes: 14 additions & 172 deletions filter.go
Original file line number Diff line number Diff line change
@@ -1,181 +1,23 @@
package filter

import (
"net"
"sync"
import "github.com/multiformats/go-multiaddr"

ma "github.com/multiformats/go-multiaddr"
)

// Action is an enum modelling all possible filter actions.
type Action int32
// Deprecated. Use "github.com/multiformats/go-multiaddr".Action instead.
type Action = multiaddr.Action

const (
ActionNone Action = iota // zero value.
ActionAccept
ActionDeny
// Deprecated. Use "github.com/multiformats/go-multiaddr".ActionNone instead.
ActionNone = multiaddr.ActionNone
// Deprecated. Use "github.com/multiformats/go-multiaddr".ActionAccept instead.
ActionAccept = multiaddr.ActionAccept
// Deprecated. Use "github.com/multiformats/go-multiaddr".ActionDeny instead.
ActionDeny = multiaddr.ActionDeny
)

type filterEntry struct {
f net.IPNet
action Action
}

// Filters is a structure representing a collection of accept/deny
// net.IPNet filters, together with the DefaultAction flag, which
// represents the default filter policy.
//
// Note that the last policy added to the Filters is authoritative.
type Filters struct {
DefaultAction Action

mu sync.RWMutex
filters []*filterEntry
}

// NewFilters constructs and returns a new set of net.IPNet filters.
// By default, the new filter accepts all addresses.
func NewFilters() *Filters {
return &Filters{
DefaultAction: ActionAccept,
filters: make([]*filterEntry, 0),
}
}

func (fs *Filters) find(ipnet net.IPNet) (int, *filterEntry) {
s := ipnet.String()
for idx, ft := range fs.filters {
if ft.f.String() == s {
return idx, ft
}
}
return -1, nil
}

// AddDialFilter adds a deny rule to this Filters set. Hosts
// matching the given net.IPNet filter will be denied, unless
// another rule is added which states that they should be accepted.
//
// No effort is made to prevent duplication of filters, or to simplify
// the filters list.
//
// Deprecated: Use AddFilter().
func (fs *Filters) AddDialFilter(f *net.IPNet) {
fs.AddFilter(*f, ActionDeny)
}

// AddFilter adds a rule to the Filters set, enforcing the desired action for
// the provided IPNet mask.
func (fs *Filters) AddFilter(ipnet net.IPNet, action Action) {
fs.mu.Lock()
defer fs.mu.Unlock()

if _, f := fs.find(ipnet); f != nil {
f.action = action
} else {
fs.filters = append(fs.filters, &filterEntry{ipnet, action})
}
}

// RemoveLiteral removes the first filter associated with the supplied IPNet,
// returning whether something was removed or not. It makes no distinction
// between whether the rule is an accept or a deny.
//
// Deprecated: use RemoveLiteral() instead.
func (fs *Filters) Remove(ipnet *net.IPNet) (removed bool) {
return fs.RemoveLiteral(*ipnet)
}

// RemoveLiteral removes the first filter associated with the supplied IPNet,
// returning whether something was removed or not. It makes no distinction
// between whether the rule is an accept or a deny.
func (fs *Filters) RemoveLiteral(ipnet net.IPNet) (removed bool) {
fs.mu.Lock()
defer fs.mu.Unlock()

if idx, _ := fs.find(ipnet); idx != -1 {
fs.filters = append(fs.filters[:idx], fs.filters[idx+1:]...)
return true
}
return false
}

// AddrBlocked parses a ma.Multiaddr and, if a valid netip is found, it applies the
// Filter set rules, returning true if the given address should be denied, and false if
// the given address is accepted.
//
// If a parsing error occurs, or no filter matches, the Filters'
// default is returned.
//
// TODO: currently, the last filter to match wins always, but it shouldn't be that way.
// Instead, the highest-specific last filter should win; that way more specific filters
// override more general ones.
func (fs *Filters) AddrBlocked(a ma.Multiaddr) (deny bool) {
var (
netip net.IP
found bool
)

ma.ForEach(a, func(c ma.Component) bool {
switch c.Protocol().Code {
case ma.P_IP6ZONE:
return true
case ma.P_IP6, ma.P_IP4:
found = true
netip = net.IP(c.RawValue())
return false
default:
return false
}
})

if !found {
return fs.DefaultAction == ActionDeny
}

fs.mu.RLock()
defer fs.mu.RUnlock()

action := fs.DefaultAction
for _, ft := range fs.filters {
if ft.f.Contains(netip) {
action = ft.action
}
}

return action == ActionDeny
}

// Filters returns the list of DENY net.IPNet masks. For backwards compatibility.
//
// A copy of the filters is made prior to returning, so the inner state is not exposed.
//
// Deprecated: Use FiltersForAction().
func (fs *Filters) Filters() (result []*net.IPNet) {
ffa := fs.FiltersForAction(ActionDeny)
for _, res := range ffa {
res := res // allocate a new copy
result = append(result, &res)
}
return result
}

func (fs *Filters) ActionForFilter(ipnet net.IPNet) (action Action, ok bool) {
if _, f := fs.find(ipnet); f != nil {
return f.action, true
}
return ActionNone, false
}

// FiltersForAction returns the filters associated with the indicated action.
func (fs *Filters) FiltersForAction(action Action) (result []net.IPNet) {
fs.mu.RLock()
defer fs.mu.RUnlock()
// Deprecated. Use "github.com/multiformats/go-multiaddr".Filters instead.
type Filters = multiaddr.Filters

for _, ff := range fs.filters {
if ff.action == action {
result = append(result, ff.f)
}
}
return result
// Deprecated. Use "github.com/multiformats/go-multiaddr".NewFilters instead.
func NewFilters() *multiaddr.Filters {
return multiaddr.NewFilters()
}
Loading