mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-19 20:32:35 +02:00
fix: acl matcher parsing, refactor
This commit is contained in:
parent
1e24765b17
commit
44b4cff35e
2 changed files with 35 additions and 33 deletions
|
@ -133,19 +133,15 @@ func (c *Config) IPAllowed(ip net.IP) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
ipAndStr := &maxmind.IPInfo{IP: ip, Str: ipStr}
|
ipAndStr := &maxmind.IPInfo{IP: ip, Str: ipStr}
|
||||||
for _, m := range c.Allow {
|
if c.Allow.Match(ipAndStr) {
|
||||||
if m(ipAndStr) {
|
c.log(ipAndStr, true)
|
||||||
c.log(ipAndStr, true)
|
c.cacheRecord(ipAndStr, true)
|
||||||
c.cacheRecord(ipAndStr, true)
|
return true
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for _, m := range c.Deny {
|
if c.Deny.Match(ipAndStr) {
|
||||||
if m(ipAndStr) {
|
c.log(ipAndStr, false)
|
||||||
c.log(ipAndStr, false)
|
c.cacheRecord(ipAndStr, false)
|
||||||
c.cacheRecord(ipAndStr, false)
|
return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log(ipAndStr, c.defaultAllow)
|
c.log(ipAndStr, c.defaultAllow)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package acl
|
package acl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -8,7 +9,11 @@ import (
|
||||||
"github.com/yusing/go-proxy/internal/maxmind"
|
"github.com/yusing/go-proxy/internal/maxmind"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Matcher func(*maxmind.IPInfo) bool
|
type MatcherFunc func(*maxmind.IPInfo) bool
|
||||||
|
|
||||||
|
type Matcher struct {
|
||||||
|
match MatcherFunc
|
||||||
|
}
|
||||||
|
|
||||||
type Matchers []Matcher
|
type Matchers []Matcher
|
||||||
|
|
||||||
|
@ -29,68 +34,69 @@ var errMatcherFormat = gperr.Multiline().AddLines(
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errSyntax = gperr.New("syntax error")
|
errSyntax = errors.New("syntax error")
|
||||||
errInvalidIP = gperr.New("invalid IP")
|
errInvalidIP = errors.New("invalid IP")
|
||||||
errInvalidCIDR = gperr.New("invalid CIDR")
|
errInvalidCIDR = errors.New("invalid CIDR")
|
||||||
errMaxMindNotConfigured = gperr.New("MaxMind not configured")
|
errMaxMindNotConfigured = errors.New("MaxMind not configured")
|
||||||
)
|
)
|
||||||
|
|
||||||
func ParseMatcher(s string) (Matcher, gperr.Error) {
|
func (matcher *Matcher) Parse(s string) error {
|
||||||
parts := strings.Split(s, ":")
|
parts := strings.Split(s, ":")
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
return nil, errSyntax
|
return errSyntax
|
||||||
}
|
}
|
||||||
|
|
||||||
switch parts[0] {
|
switch parts[0] {
|
||||||
case MatcherTypeIP:
|
case MatcherTypeIP:
|
||||||
ip := net.ParseIP(parts[1])
|
ip := net.ParseIP(parts[1])
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return nil, errInvalidIP
|
return errInvalidIP
|
||||||
}
|
}
|
||||||
return matchIP(ip), nil
|
matcher.match = matchIP(ip)
|
||||||
case MatcherTypeCIDR:
|
case MatcherTypeCIDR:
|
||||||
_, net, err := net.ParseCIDR(parts[1])
|
_, net, err := net.ParseCIDR(parts[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errInvalidCIDR
|
return errInvalidCIDR
|
||||||
}
|
}
|
||||||
return matchCIDR(net), nil
|
matcher.match = matchCIDR(net)
|
||||||
case MatcherTypeTimeZone:
|
case MatcherTypeTimeZone:
|
||||||
if !maxmind.HasInstance() {
|
if !maxmind.HasInstance() {
|
||||||
return nil, errMaxMindNotConfigured
|
return errMaxMindNotConfigured
|
||||||
}
|
}
|
||||||
return matchTimeZone(parts[1]), nil
|
matcher.match = matchTimeZone(parts[1])
|
||||||
case MatcherTypeCountry:
|
case MatcherTypeCountry:
|
||||||
if !maxmind.HasInstance() {
|
if !maxmind.HasInstance() {
|
||||||
return nil, errMaxMindNotConfigured
|
return errMaxMindNotConfigured
|
||||||
}
|
}
|
||||||
return matchISOCode(parts[1]), nil
|
matcher.match = matchISOCode(parts[1])
|
||||||
default:
|
default:
|
||||||
return nil, errSyntax
|
return errSyntax
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (matchers Matchers) Match(ip *maxmind.IPInfo) bool {
|
func (matchers Matchers) Match(ip *maxmind.IPInfo) bool {
|
||||||
for _, m := range matchers {
|
for _, m := range matchers {
|
||||||
if m(ip) {
|
if m.match(ip) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchIP(ip net.IP) Matcher {
|
func matchIP(ip net.IP) MatcherFunc {
|
||||||
return func(ip2 *maxmind.IPInfo) bool {
|
return func(ip2 *maxmind.IPInfo) bool {
|
||||||
return ip.Equal(ip2.IP)
|
return ip.Equal(ip2.IP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchCIDR(n *net.IPNet) Matcher {
|
func matchCIDR(n *net.IPNet) MatcherFunc {
|
||||||
return func(ip *maxmind.IPInfo) bool {
|
return func(ip *maxmind.IPInfo) bool {
|
||||||
return n.Contains(ip.IP)
|
return n.Contains(ip.IP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchTimeZone(tz string) Matcher {
|
func matchTimeZone(tz string) MatcherFunc {
|
||||||
return func(ip *maxmind.IPInfo) bool {
|
return func(ip *maxmind.IPInfo) bool {
|
||||||
city, ok := maxmind.LookupCity(ip)
|
city, ok := maxmind.LookupCity(ip)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -100,7 +106,7 @@ func matchTimeZone(tz string) Matcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchISOCode(iso string) Matcher {
|
func matchISOCode(iso string) MatcherFunc {
|
||||||
return func(ip *maxmind.IPInfo) bool {
|
return func(ip *maxmind.IPInfo) bool {
|
||||||
city, ok := maxmind.LookupCity(ip)
|
city, ok := maxmind.LookupCity(ip)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
Loading…
Add table
Reference in a new issue