diff --git a/README.md b/README.md index dd1219c..e65d802 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,10 @@ docker run --name yao-proxy --net=host --restart=always -v :/e ## 更新说明 +### v2.2.3 + +- 过滤规则增加ipv4区间写法,参考[local-config](cmd/local/res/config.json) + ### v2.2.2 - 本地代理新增过滤规则,可以不代理指定的域名或者IP地址,写法参考[local-config](cmd/local/res/config.json) diff --git a/cmd/local/res/config.json b/cmd/local/res/config.json index 2e23228..b115b45 100644 --- a/cmd/local/res/config.json +++ b/cmd/local/res/config.json @@ -27,7 +27,8 @@ ], "no_proxy": [ "baidu.com", - "192.168.1.x" + "172.16.x.x", + "192.168.1.170-192.168.1.200" ] }, { diff --git a/internal/service/local/no_proxy.go b/internal/service/local/no_proxy.go index 8d41e88..074bd0c 100644 --- a/internal/service/local/no_proxy.go +++ b/internal/service/local/no_proxy.go @@ -1,6 +1,8 @@ package local import ( + "encoding/binary" + "net" "regexp" "strings" ) @@ -14,48 +16,79 @@ import ( */ const ( - IPv4Expr = `^(\d+?\.){3}\d+$` - IPv4XExpr = `^(\d+?\.|[x]\.){3}\d+$` + IPv4Expr = `^(\d+?\.){3}\d+$` + IPv4XExpr = `^(\d+?\.|[x]\.){3}\d+$` Ipv4RangeExpr = `^(\d+?\.){3}\d+?-(\d+?\.){3}\d+$` ) var ( - IPv4Cpl = regexp.MustCompile(IPv4Expr) - IPv4XCpl = regexp.MustCompile(IPv4XExpr) + IPv4Cpl = regexp.MustCompile(IPv4Expr) + IPv4XCpl = regexp.MustCompile(IPv4XExpr) IPv4RangeCpl = regexp.MustCompile(Ipv4RangeExpr) + + prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255} ) type Filter struct { re []*regexp.Regexp + mp map[string]struct{} } func NewFilter(raw []string) *Filter { re := make([]*regexp.Regexp, 0) - - for _, r := range raw{ - if IPv4Cpl.MatchString(r){ - // 纯 IPv4 什么都不处理 - }else if IPv4XCpl.MatchString(r){ + mp := make(map[string]struct{}) + for _, r := range raw { + if IPv4Cpl.MatchString(r) { + // 纯 IPv4 do nothing + re = append(re, regexp.MustCompile(r)) + } else if IPv4XCpl.MatchString(r) { // 将 x 替换为 \d+? r = strings.Replace(r, "x", `\d+?`, -1) - }else if IPv4RangeCpl.MatchString(r){ - // todo 暂时不处理范围匹配 - } + re = append(re, regexp.MustCompile(r)) + } else if IPv4RangeCpl.MatchString(r) { + ips := strings.Split(r, "-") + ip1 := binary.BigEndian.Uint32(net.ParseIP(ips[0])[12:]) + ip2 := binary.BigEndian.Uint32(net.ParseIP(ips[1])[12:]) + if ip2 < ip1 { // ip2 不可以小于 ip1 + continue + } + + for i := ip1; i <= ip2; i++ { + ipBts := make([]byte, 4) + binary.BigEndian.PutUint32(ipBts, i) + ip := append(prefix, ipBts...) - re = append(re, regexp.MustCompile(r)) + a := net.IP(ip) + mp[a.String()] = struct{}{} + } + + continue + }else{ + // 这种情况是域名,需要解析出真实IP地址 再保存一份其IP + re = append(re, regexp.MustCompile(r)) + ip, err := net.ResolveIPAddr("ip", r) + if err != nil { + continue + } + re = append(re, regexp.MustCompile(ip.String())) + } } return &Filter{ re: re, + mp: mp, } } -func (f *Filter) Check(str string) bool { - for _, r := range f.re{ - if r.MatchString(str){ +func (f *Filter) Check(host string) bool { + ip := strings.Split(host, ":")[0] + for _, r := range f.re { + if r.MatchString(ip) { return true } } - return false + _, ok := f.mp[ip] + + return ok }