Initial commit (code only without large binaries)
This commit is contained in:
282
EdgeCommon/pkg/dnsconfigs/ns_route_ranges.go
Normal file
282
EdgeCommon/pkg/dnsconfigs/ns_route_ranges.go
Normal file
@@ -0,0 +1,282 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build plus
|
||||
|
||||
package dnsconfigs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"net"
|
||||
)
|
||||
|
||||
type NSRouteRangeType = string
|
||||
|
||||
const (
|
||||
NSRouteRangeTypeIP NSRouteRangeType = "ipRange" // IP范围
|
||||
NSRouteRangeTypeCIDR NSRouteRangeType = "cidr" // CIDR
|
||||
NSRouteRangeTypeRegion NSRouteRangeType = "region" // 区域
|
||||
)
|
||||
|
||||
func AllNSRouteRangeTypes() []*shared.Definition {
|
||||
return []*shared.Definition{
|
||||
{
|
||||
Name: "IP范围",
|
||||
Code: NSRouteRangeTypeIP,
|
||||
},
|
||||
{
|
||||
Name: "CIDR",
|
||||
Code: NSRouteRangeTypeCIDR,
|
||||
},
|
||||
{
|
||||
Name: "区域",
|
||||
Code: NSRouteRangeTypeRegion,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NSRouteRegionResolver 解析IP接口
|
||||
type NSRouteRegionResolver interface {
|
||||
Resolve(ip net.IP) (countryId int64, provinceId int64, cityId int64, providerId int64)
|
||||
}
|
||||
|
||||
// NSRouteRangeInterface 线路范围接口
|
||||
type NSRouteRangeInterface interface {
|
||||
// Init 初始化
|
||||
Init() error
|
||||
|
||||
// Contains 判断是否包含
|
||||
Contains(ip net.IP) bool
|
||||
|
||||
// SetRegionResolver 设置IP解析接口
|
||||
SetRegionResolver(resolver NSRouteRegionResolver)
|
||||
|
||||
// IsExcluding 是否为排除
|
||||
IsExcluding() bool
|
||||
}
|
||||
|
||||
type NSBaseRouteRange struct {
|
||||
IsReverse bool `json:"isReverse"`
|
||||
|
||||
routeRegionResolver NSRouteRegionResolver
|
||||
}
|
||||
|
||||
func (this *NSBaseRouteRange) SetRegionResolver(resolver NSRouteRegionResolver) {
|
||||
this.routeRegionResolver = resolver
|
||||
}
|
||||
|
||||
func (this *NSBaseRouteRange) IsExcluding() bool {
|
||||
return this.IsReverse
|
||||
}
|
||||
|
||||
// NSRouteRangeIPRange IP范围配置
|
||||
// IPv4和IPv6不能混用
|
||||
type NSRouteRangeIPRange struct {
|
||||
NSBaseRouteRange
|
||||
|
||||
IPFrom string `json:"ipFrom"`
|
||||
IPTo string `json:"ipTo"`
|
||||
|
||||
ipFrom iputils.IP
|
||||
ipTo iputils.IP
|
||||
|
||||
ipVersion int // 4|6
|
||||
}
|
||||
|
||||
func (this *NSRouteRangeIPRange) Init() error {
|
||||
var ipFrom = net.ParseIP(this.IPFrom)
|
||||
var ipTo = net.ParseIP(this.IPTo)
|
||||
if ipFrom == nil {
|
||||
return errors.New("invalid ipFrom '" + this.IPFrom + "'")
|
||||
}
|
||||
if ipTo == nil {
|
||||
return errors.New("invalid ipTo '" + this.IPTo + "'")
|
||||
}
|
||||
|
||||
var ipFromVersion = configutils.IPVersion(ipFrom)
|
||||
var ipToVersion = configutils.IPVersion(ipTo)
|
||||
if ipFromVersion != ipToVersion {
|
||||
return errors.New("ipFrom and ipTo version are not same")
|
||||
}
|
||||
this.ipVersion = ipFromVersion
|
||||
|
||||
this.ipFrom = iputils.NewIP(ipFrom)
|
||||
this.ipTo = iputils.NewIP(ipTo)
|
||||
|
||||
if this.ipFrom.Compare(this.ipTo) > 0 {
|
||||
this.ipFrom, this.ipTo = this.ipTo, this.ipFrom
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *NSRouteRangeIPRange) Contains(netIP net.IP) bool {
|
||||
if len(netIP) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var version = configutils.IPVersion(netIP)
|
||||
if version != this.ipVersion {
|
||||
return false
|
||||
}
|
||||
|
||||
return iputils.NewIP(netIP).Between(this.ipFrom, this.ipTo)
|
||||
}
|
||||
|
||||
// NSRouteRangeCIDR CIDR范围配置
|
||||
type NSRouteRangeCIDR struct {
|
||||
NSBaseRouteRange
|
||||
|
||||
CIDR string `json:"cidr"`
|
||||
|
||||
cidr *net.IPNet
|
||||
}
|
||||
|
||||
func (this *NSRouteRangeCIDR) Init() error {
|
||||
_, ipNet, err := net.ParseCIDR(this.CIDR)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parse cidr failed: %w", err)
|
||||
}
|
||||
|
||||
this.cidr = ipNet
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *NSRouteRangeCIDR) Contains(netIP net.IP) bool {
|
||||
if netIP == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if this.cidr == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return this.cidr.Contains(netIP)
|
||||
}
|
||||
|
||||
// NSRouteRangeRegion 区域范围
|
||||
// country:ID, province:ID, city:ID, isp:ID
|
||||
type NSRouteRangeRegion struct {
|
||||
NSBaseRouteRange
|
||||
|
||||
Regions []*RouteRegion `json:"regions"`
|
||||
Connector string `json:"connector"` // AND | OR
|
||||
}
|
||||
|
||||
func (this *NSRouteRangeRegion) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *NSRouteRangeRegion) Contains(netIP net.IP) bool {
|
||||
if this.routeRegionResolver == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(this.Regions) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
countryId, provinceId, cityId, providerId := this.routeRegionResolver.Resolve(netIP)
|
||||
if countryId <= 0 && provinceId <= 0 && cityId <= 0 && providerId <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var matchAll = this.Connector == "AND"
|
||||
for _, region := range this.Regions {
|
||||
if region.Id <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
switch region.Type {
|
||||
case "country":
|
||||
if region.Id == countryId {
|
||||
if !matchAll {
|
||||
return true
|
||||
}
|
||||
} else if matchAll {
|
||||
return false
|
||||
}
|
||||
case "province":
|
||||
if region.Id == provinceId {
|
||||
if !matchAll {
|
||||
return true
|
||||
}
|
||||
} else if matchAll {
|
||||
return false
|
||||
}
|
||||
case "city":
|
||||
if region.Id == cityId {
|
||||
if !matchAll {
|
||||
return true
|
||||
}
|
||||
} else if matchAll {
|
||||
return false
|
||||
}
|
||||
case "provider":
|
||||
if region.Id == providerId {
|
||||
if !matchAll {
|
||||
return true
|
||||
}
|
||||
} else if matchAll {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matchAll
|
||||
}
|
||||
|
||||
type RouteRegion struct {
|
||||
Type string `json:"type"` // country|province|city|isp
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// InitNSRangesFromJSON 从JSON中初始化线路范围
|
||||
func InitNSRangesFromJSON(rangesJSON []byte) (ranges []NSRouteRangeInterface, err error) {
|
||||
if len(rangesJSON) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var rangeMaps = []maps.Map{}
|
||||
err = json.Unmarshal(rangesJSON, &rangeMaps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, rangeMap := range rangeMaps {
|
||||
var rangeType = rangeMap.GetString("type")
|
||||
paramsJSON, err := json.Marshal(rangeMap.Get("params"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var r NSRouteRangeInterface
|
||||
|
||||
switch rangeType {
|
||||
case NSRouteRangeTypeIP:
|
||||
r = &NSRouteRangeIPRange{}
|
||||
case NSRouteRangeTypeCIDR:
|
||||
r = &NSRouteRangeCIDR{}
|
||||
case NSRouteRangeTypeRegion:
|
||||
r = &NSRouteRangeRegion{}
|
||||
default:
|
||||
return nil, errors.New("invalid route line type '" + rangeType + "'")
|
||||
}
|
||||
|
||||
err = json.Unmarshal(paramsJSON, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = r.Init()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ranges = append(ranges, r)
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user