x/admission/admission.go

83 lines
1.7 KiB
Go

package admission
import (
"net"
admission_pkg "github.com/go-gost/core/admission"
"github.com/go-gost/core/logger"
"github.com/go-gost/x/internal/util/matcher"
)
type options struct {
logger logger.Logger
}
type Option func(opts *options)
func LoggerOption(logger logger.Logger) Option {
return func(opts *options) {
opts.logger = logger
}
}
type admission struct {
ipMatcher matcher.Matcher
cidrMatcher matcher.Matcher
reversed bool
options options
}
// NewAdmissionPatterns creates and initializes a new Admission using matcher patterns as its match rules.
// The rules will be reversed if the reverse is true.
func NewAdmission(reversed bool, patterns []string, opts ...Option) admission_pkg.Admission {
var options options
for _, opt := range opts {
opt(&options)
}
var ips []net.IP
var inets []*net.IPNet
for _, pattern := range patterns {
if ip := net.ParseIP(pattern); ip != nil {
ips = append(ips, ip)
continue
}
if _, inet, err := net.ParseCIDR(pattern); err == nil {
inets = append(inets, inet)
continue
}
}
return &admission{
reversed: reversed,
options: options,
ipMatcher: matcher.IPMatcher(ips),
cidrMatcher: matcher.CIDRMatcher(inets),
}
}
func (p *admission) Admit(addr string) bool {
if addr == "" || p == nil {
p.options.logger.Debugf("admission: %v is denied", addr)
return false
}
// try to strip the port
if host, _, _ := net.SplitHostPort(addr); host != "" {
addr = host
}
matched := p.matched(addr)
b := !p.reversed && matched ||
p.reversed && !matched
if !b {
p.options.logger.Debugf("admission: %v is denied", addr)
}
return b
}
func (p *admission) matched(addr string) bool {
return p.ipMatcher.Match(addr) ||
p.cidrMatcher.Match(addr)
}