feat: full geoip/geosite support

This commit is contained in:
Toby
2023-10-28 13:55:20 -07:00
parent bcacc46f1d
commit e604c12f7e
18 changed files with 674 additions and 229 deletions

View File

@@ -4,12 +4,25 @@ import (
"net"
"testing"
"github.com/oschwald/geoip2-golang"
"github.com/apernet/hysteria/extras/outbounds/acl/v2geo"
"github.com/stretchr/testify/assert"
)
var _ GeoLoader = (*testGeoLoader)(nil)
type testGeoLoader struct{}
func (l *testGeoLoader) LoadGeoIP() (map[string]*v2geo.GeoIP, error) {
return v2geo.LoadGeoIP("v2geo/geoip.dat")
}
func (l *testGeoLoader) LoadGeoSite() (map[string]*v2geo.GeoSite, error) {
return v2geo.LoadGeoSite("v2geo/geosite.dat")
}
func TestCompile(t *testing.T) {
ob1, ob2, ob3 := 1, 2, 3
ob1, ob2, ob3, ob4 := 1, 2, 3, 4
rules := []TextRule{
{
Outbound: "ob1",
@@ -59,12 +72,25 @@ func TestCompile(t *testing.T) {
ProtoPort: "*/*",
HijackAddress: "",
},
{
Outbound: "ob4",
Address: "geosite:4chan",
ProtoPort: "*/*",
HijackAddress: "",
},
{
Outbound: "ob4",
Address: "geosite:google @cn",
ProtoPort: "*/*",
HijackAddress: "",
},
}
reader, err := geoip2.Open("GeoLite2-Country.mmdb")
assert.NoError(t, err)
comp, err := Compile[int](rules, map[string]int{"ob1": ob1, "ob2": ob2, "ob3": ob3}, 100, func() *geoip2.Reader {
return reader
})
comp, err := Compile[int](rules, map[string]int{
"ob1": ob1,
"ob2": ob2,
"ob3": ob3,
"ob4": ob4,
}, 100, &testGeoLoader{})
assert.NoError(t, err)
tests := []struct {
@@ -146,6 +172,42 @@ func TestCompile(t *testing.T) {
wantOutbound: ob2,
wantIP: nil,
},
{
host: HostInfo{
IPv4: net.ParseIP("175.45.176.73"),
},
proto: ProtocolTCP,
port: 80,
wantOutbound: 0, // no match default
wantIP: nil,
},
{
host: HostInfo{
Name: "boards.4channel.org",
},
proto: ProtocolTCP,
port: 443,
wantOutbound: ob4,
wantIP: nil,
},
{
host: HostInfo{
Name: "gstatic-cn.com",
},
proto: ProtocolUDP,
port: 9999,
wantOutbound: ob4,
wantIP: nil,
},
{
host: HostInfo{
Name: "hoho.waymo.com",
},
proto: ProtocolUDP,
port: 9999,
wantOutbound: 0, // no match default
wantIP: nil,
},
}
for _, test := range tests {
@@ -154,3 +216,56 @@ func TestCompile(t *testing.T) {
assert.Equal(t, test.wantIP, gotIP)
}
}
func Test_parseGeoSiteName(t *testing.T) {
tests := []struct {
name string
s string
want string
want1 []string
}{
{
name: "no attrs",
s: "pornhub",
want: "pornhub",
want1: []string{},
},
{
name: "one attr 1",
s: "xiaomi@cn",
want: "xiaomi",
want1: []string{"cn"},
},
{
name: "one attr 2",
s: " google @jp ",
want: "google",
want1: []string{"jp"},
},
{
name: "two attrs 1",
s: "netflix@jp@kr",
want: "netflix",
want1: []string{"jp", "kr"},
},
{
name: "two attrs 2",
s: "netflix @xixi @haha ",
want: "netflix",
want1: []string{"xixi", "haha"},
},
{
name: "empty",
s: "",
want: "",
want1: []string{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1 := parseGeoSiteName(tt.s)
assert.Equalf(t, tt.want, got, "parseGeoSiteName(%v)", tt.s)
assert.Equalf(t, tt.want1, got1, "parseGeoSiteName(%v)", tt.s)
})
}
}