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

Commit

Permalink
deprecate this package; moved to multiformats/go-multiaddr. (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
raulk authored May 14, 2020
1 parent 992f8b7 commit 29ae229
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 391 deletions.
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

0 comments on commit 29ae229

Please sign in to comment.