package multiaddrimport ()// Action is an enum modelling all possible filter actions.typeActionint32const (ActionNoneAction = iota// zero value.ActionAcceptActionDeny)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.typeFiltersstruct { 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 () *Filters {return &Filters{DefaultAction: ActionAccept,filters: make([]*filterEntry, 0), }}func ( *Filters) ( net.IPNet) (int, *filterEntry) { := .String()for , := range .filters {if .f.String() == {return , } }return -1, nil}// AddFilter adds a rule to the Filters set, enforcing the desired action for// the provided IPNet mask.func ( *Filters) ( net.IPNet, Action) { .mu.Lock()defer .mu.Unlock()if , := .find(); != nil { .action = } else { .filters = append(.filters, &filterEntry{, }) }}// 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 ( *Filters) ( net.IPNet) ( bool) { .mu.Lock()defer .mu.Unlock()if , := .find(); != -1 { .filters = append(.filters[:], .filters[+1:]...)returntrue }returnfalse}// 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 ( *Filters) ( Multiaddr) ( bool) {var (net.IPbool )ForEach(, func( Component) bool {switch .Protocol().Code {caseP_IP6ZONE:returntruecaseP_IP6, P_IP4: = true = net.IP(.RawValue())returnfalsedefault:returnfalse } })if ! {return .DefaultAction == ActionDeny } .mu.RLock()defer .mu.RUnlock() := .DefaultActionfor , := range .filters {if .f.Contains() { = .action } }return == ActionDeny}func ( *Filters) ( net.IPNet) ( Action, bool) {if , := .find(); != nil {return .action, true }returnActionNone, false}// FiltersForAction returns the filters associated with the indicated action.func ( *Filters) ( Action) ( []net.IPNet) { .mu.RLock()defer .mu.RUnlock()for , := range .filters {if .action == { = append(, .f) } }return}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.