mirror of
https://github.com/apernet/hysteria.git
synced 2025-04-03 20:47:38 +03:00
support range format ProtoPort
This commit is contained in:
parent
02baab148a
commit
ee056deaad
2 changed files with 115 additions and 0 deletions
|
@ -107,6 +107,11 @@ type GeoLoader interface {
|
||||||
func Compile[O Outbound](rules []TextRule, outbounds map[string]O,
|
func Compile[O Outbound](rules []TextRule, outbounds map[string]O,
|
||||||
cacheSize int, geoLoader GeoLoader,
|
cacheSize int, geoLoader GeoLoader,
|
||||||
) (CompiledRuleSet[O], error) {
|
) (CompiledRuleSet[O], error) {
|
||||||
|
for _, rule := range rules {
|
||||||
|
if extra, rangeLen := splitPortRangeRules(&rule); rangeLen > 0 {
|
||||||
|
rules = append(rules, extra...)
|
||||||
|
}
|
||||||
|
}
|
||||||
compiledRules := make([]compiledRule[O], len(rules))
|
compiledRules := make([]compiledRule[O], len(rules))
|
||||||
for i, rule := range rules {
|
for i, rule := range rules {
|
||||||
outbound, ok := outbounds[strings.ToLower(rule.Outbound)]
|
outbound, ok := outbounds[strings.ToLower(rule.Outbound)]
|
||||||
|
@ -282,3 +287,40 @@ func parseGeoSiteName(s string) (string, []string) {
|
||||||
}
|
}
|
||||||
return base, attrs
|
return base, attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func splitPortRangeRules(rule *TextRule) ([]TextRule, int) {
|
||||||
|
protoPort := strings.ToLower(rule.ProtoPort)
|
||||||
|
if protoPort == "" || protoPort == "*" || protoPort == "*/*" {
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
parts := strings.SplitN(protoPort, "/", 2)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
ports := strings.SplitN(strings.TrimSpace(parts[1]), "-", 2)
|
||||||
|
if len(ports) != 2 {
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
minPorts, err := strconv.Atoi(ports[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
maxPorts, err := strconv.Atoi(ports[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
portLength := maxPorts - minPorts
|
||||||
|
if portLength <= 0 || minPorts == 0 {
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// port range: minPort < port <= MaxPort
|
||||||
|
extraRules := make([]TextRule, portLength)
|
||||||
|
for i := range extraRules {
|
||||||
|
extraRules[i] = *rule
|
||||||
|
extraRules[i].ProtoPort = fmt.Sprintf("%s/%d", parts[0], minPorts+i+1)
|
||||||
|
}
|
||||||
|
rule.ProtoPort = fmt.Sprintf("%s/%d", parts[0], minPorts)
|
||||||
|
return extraRules, portLength
|
||||||
|
}
|
||||||
|
|
|
@ -303,3 +303,76 @@ func Test_parseGeoSiteName(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_splitPortRangeRules(t *testing.T) {
|
||||||
|
rules := []TextRule{
|
||||||
|
{
|
||||||
|
Outbound: "ob1",
|
||||||
|
Address: "1.2.3.4",
|
||||||
|
ProtoPort: "tcp/1-1024",
|
||||||
|
HijackAddress: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Outbound: "ob1",
|
||||||
|
Address: "1.2.3.4",
|
||||||
|
ProtoPort: "udp/1-1024",
|
||||||
|
HijackAddress: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Outbound: "ob1",
|
||||||
|
Address: "1.2.3.4",
|
||||||
|
ProtoPort: "*/1-1024",
|
||||||
|
HijackAddress: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Outbound: "ob1",
|
||||||
|
Address: "1.2.3.4",
|
||||||
|
ProtoPort: "tcp/0-222",
|
||||||
|
HijackAddress: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Outbound: "ob1",
|
||||||
|
Address: "1.2.3.4",
|
||||||
|
ProtoPort: "tcp/1024",
|
||||||
|
HijackAddress: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Outbound: "ob1",
|
||||||
|
Address: "1.2.3.4",
|
||||||
|
ProtoPort: "tcp/-1-9",
|
||||||
|
HijackAddress: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Outbound: "ob1",
|
||||||
|
Address: "1.2.3.4",
|
||||||
|
ProtoPort: "tcp/6881-6889",
|
||||||
|
HijackAddress: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, rangeLen0 := splitPortRangeRules(&rules[0])
|
||||||
|
assert.Equal(t, 1023, rangeLen0)
|
||||||
|
|
||||||
|
_, rangeLen1 := splitPortRangeRules(&rules[1])
|
||||||
|
assert.Equal(t, 1023, rangeLen1)
|
||||||
|
|
||||||
|
_, rangeLen2 := splitPortRangeRules(&rules[2])
|
||||||
|
assert.Equal(t, 1023, rangeLen2)
|
||||||
|
|
||||||
|
_, rangeLen3 := splitPortRangeRules(&rules[3])
|
||||||
|
assert.Equal(t, 0, rangeLen3)
|
||||||
|
|
||||||
|
_, rangeLen4 := splitPortRangeRules(&rules[4])
|
||||||
|
assert.Equal(t, 0, rangeLen4)
|
||||||
|
|
||||||
|
_, rangeLen5 := splitPortRangeRules(&rules[5])
|
||||||
|
assert.Equal(t, 0, rangeLen5)
|
||||||
|
|
||||||
|
rangeRule, _ := splitPortRangeRules(&rules[6])
|
||||||
|
for _, rule := range rangeRule {
|
||||||
|
assert.Equal(t, "ob1", rule.Outbound)
|
||||||
|
assert.Equal(t, "1.2.3.4", rule.Address)
|
||||||
|
t.Log(rule.ProtoPort)
|
||||||
|
assert.Equal(t, "", rule.HijackAddress)
|
||||||
|
}
|
||||||
|
assert.Equal(t, "tcp/6881", rules[6].ProtoPort)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue