segments iterate with CIDR supports
This commit is contained in:
parent
f939363a19
commit
072b6fed24
|
|
@ -3,8 +3,16 @@
|
|||
192.168.2.31|192.168.2.60|0|0|内网IP|办公室B
|
||||
192.168.2.61|192.168.2.91|0|0|内网IP|办公室B
|
||||
223.255.236.0|223.255.239.255|中国|上海|上海市|电信
|
||||
# ipv4 cidr
|
||||
14.32.46.0/24|3491 4766 9696|IGP
|
||||
24.104.37.0/24|14537 174 7922 7016 401657 401657|IGP
|
||||
45.15.32.0/22|14537 29119 206496 206496 206496 206496 206496 206496 206496 206496 206496|IGP
|
||||
2c0f:fff1::|2c0f:ffff:ffff:ffff:ffff:ffff:ffff:ffff|毛里求斯|威廉平原区|卡特勒博尔纳|专线用户
|
||||
2e00::|2fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff|德国|黑森|美因河畔法兰克福|专线用户
|
||||
3000::|fbff:ffff:ffff:ffff:ffff:ffff:ffff:ffff|瑞士|弗里堡州||专线用户
|
||||
fe00::|fe7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff|瑞士|弗里堡州||专线用户
|
||||
fe80::|febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff|瑞士|弗里堡州||专线用户
|
||||
# ipv6 cidr
|
||||
2c0f:fda8::/32|4635 6939 37662 37662 37035 37349|IGP
|
||||
2c0f:fdb0::/32|3491 33765|IGP
|
||||
2c0f:fe08:7::/48|2497 6939 36914|IGP
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ type Segment struct {
|
|||
Region *Region
|
||||
}
|
||||
|
||||
func SegmentFrom(seg string, cRegion func(string) *Region) (*Segment, error) {
|
||||
func ParseSegment(seg string) ([]byte, []byte, string, error) {
|
||||
var count = 0
|
||||
var ps = StringTokenizer(strings.TrimSpace(seg), "|", func(s string, start int) bool {
|
||||
// CIDR format
|
||||
|
|
@ -36,36 +36,45 @@ func SegmentFrom(seg string, cRegion func(string) *Region) (*Segment, error) {
|
|||
rIdx = 1
|
||||
sip, eip, err = CIDR2Range(ps[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse cidr: %s", err)
|
||||
return nil, nil, "", fmt.Errorf("parse cidr: %s", err)
|
||||
}
|
||||
case 3:
|
||||
// triditional ip range
|
||||
rIdx = 2
|
||||
sip, err = ParseIP(ps[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse start ip `%s`: %s", ps[0], err)
|
||||
return nil, nil, "", fmt.Errorf("parse start ip `%s`: %s", ps[0], err)
|
||||
}
|
||||
|
||||
eip, err = ParseIP(ps[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("check end ip `%s`: %s", ps[1], err)
|
||||
return nil, nil, "", fmt.Errorf("check end ip `%s`: %s", ps[1], err)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid ip segment `%s`", seg)
|
||||
return nil, nil, "", fmt.Errorf("invalid ip segment `%s`", seg)
|
||||
}
|
||||
|
||||
if len(sip) != len(eip) {
|
||||
return nil, fmt.Errorf("invalid ip segment line `%s`, sip/eip version not match", seg)
|
||||
return nil, nil, "", fmt.Errorf("invalid ip segment line `%s`, sip/eip version not match", seg)
|
||||
}
|
||||
|
||||
if IPCompare(sip, eip) > 0 {
|
||||
return nil, fmt.Errorf("start ip(%s) should not be greater than end ip(%s)", ps[0], ps[1])
|
||||
return nil, nil, "", fmt.Errorf("start ip(%s) should not be greater than end ip(%s)", ps[0], ps[1])
|
||||
}
|
||||
|
||||
return sip, eip, ps[rIdx], nil
|
||||
}
|
||||
|
||||
func SegmentFrom(seg string, cRegion func(string) *Region) (*Segment, error) {
|
||||
sip, eip, region, err := ParseSegment(seg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Segment{
|
||||
StartIP: sip,
|
||||
EndIP: eip,
|
||||
Region: cRegion(ps[rIdx]),
|
||||
Region: cRegion(region),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -200,38 +200,14 @@ func IterateSegments(handle *os.File, autoMerge bool, before func(l string), fil
|
|||
before(l)
|
||||
}
|
||||
|
||||
var ps = strings.SplitN(l, "|", 3)
|
||||
if len(ps) != 3 {
|
||||
return totalCount, mergeCount, fmt.Errorf("invalid ip segment line `%s`", l)
|
||||
}
|
||||
|
||||
sip, err := ParseIP(ps[0])
|
||||
sip, eip, region, err := ParseSegment(l)
|
||||
if err != nil {
|
||||
return totalCount, mergeCount, fmt.Errorf("check start ip `%s`: %s", ps[0], err)
|
||||
return totalCount, mergeCount, err
|
||||
}
|
||||
|
||||
eip, err := ParseIP(ps[1])
|
||||
if err != nil {
|
||||
return totalCount, mergeCount, fmt.Errorf("check end ip `%s`: %s", ps[1], err)
|
||||
}
|
||||
|
||||
if len(sip) != len(eip) {
|
||||
return totalCount, mergeCount, fmt.Errorf("invalid ip segment line `%s`, sip/eip version not match", l)
|
||||
}
|
||||
|
||||
if IPCompare(sip, eip) > 0 {
|
||||
return totalCount, mergeCount, fmt.Errorf("start ip(%s) should not be greater than end ip(%s)", ps[0], ps[1])
|
||||
}
|
||||
|
||||
// Allow empty region info since 2024/09/24
|
||||
// if len(ps[2]) < 1 {
|
||||
// return fmt.Errorf("empty region info in segment line `%s`", l)
|
||||
// }
|
||||
|
||||
// check and do the region filter
|
||||
var region = ps[2]
|
||||
if filter != nil {
|
||||
region, err = filter(ps[2])
|
||||
region, err = filter(region)
|
||||
if err != nil {
|
||||
return totalCount, mergeCount, fmt.Errorf("failed to filter region `%s`: %s", region, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -292,12 +292,17 @@ func TestIterateSegments(t *testing.T) {
|
|||
t.Fatalf("failed to open tests file: %s", err)
|
||||
}
|
||||
|
||||
_, _, _ = IterateSegments(handle, true, func(l string) {
|
||||
total, merged, err := IterateSegments(handle, true, func(l string) {
|
||||
// fmt.Printf("load segment: `%s`\n", l)
|
||||
}, nil, NewRegion, func(seg *Segment) error {
|
||||
fmt.Printf("get segment: `%s`\n", seg)
|
||||
fmt.Printf("{%s, %s} -> `%s`\n", IP2String(seg.StartIP), IP2String(seg.EndIP), seg.Region)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("iterate error: %s", err)
|
||||
}
|
||||
|
||||
fmt.Printf("done iterate -> total:%d, merged:%d\n", total, merged)
|
||||
}
|
||||
|
||||
func TestStringTokenizer(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue