|
@@ -22,6 +22,7 @@ import (
|
|
|
|
|
|
"github.com/fatedier/frp/models/consts"
|
|
|
"github.com/fatedier/frp/models/msg"
|
|
|
+ "github.com/fatedier/frp/utils/util"
|
|
|
|
|
|
ini "github.com/vaughan0/go-ini"
|
|
|
)
|
|
@@ -770,6 +771,38 @@ func (cfg *XtcpProxyConf) Check() (err error) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+func ParseRangeSection(name string, section ini.Section) (sections map[string]ini.Section, err error) {
|
|
|
+ localPorts, errRet := util.ParseRangeNumbers(section["local_port"])
|
|
|
+ if errRet != nil {
|
|
|
+ err = fmt.Errorf("Parse conf error: range section [%s] local_port invalid, %v", name, errRet)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ remotePorts, errRet := util.ParseRangeNumbers(section["remote_port"])
|
|
|
+ if errRet != nil {
|
|
|
+ err = fmt.Errorf("Parse conf error: range section [%s] remote_port invalid, %v", name, errRet)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if len(localPorts) != len(remotePorts) {
|
|
|
+ err = fmt.Errorf("Parse conf error: range section [%s] local ports number should be same with remote ports number", name)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if len(localPorts) == 0 {
|
|
|
+ err = fmt.Errorf("Parse conf error: range section [%s] local_port and remote_port is necessary")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ sections = make(map[string]ini.Section)
|
|
|
+ for i, port := range localPorts {
|
|
|
+ subName := fmt.Sprintf("%s_%d", name, i)
|
|
|
+ subSection := copySection(section)
|
|
|
+ subSection["local_port"] = fmt.Sprintf("%d", port)
|
|
|
+ subSection["remote_port"] = fmt.Sprintf("%d", remotePorts[i])
|
|
|
+ sections[subName] = subSection
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
// if len(startProxy) is 0, start all
|
|
|
// otherwise just start proxies in startProxy map
|
|
|
func LoadProxyConfFromFile(prefix string, conf ini.File, startProxy map[string]struct{}) (
|
|
@@ -786,22 +819,51 @@ func LoadProxyConfFromFile(prefix string, conf ini.File, startProxy map[string]s
|
|
|
proxyConfs = make(map[string]ProxyConf)
|
|
|
visitorConfs = make(map[string]ProxyConf)
|
|
|
for name, section := range conf {
|
|
|
+ if name == "common" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
_, shouldStart := startProxy[name]
|
|
|
- if name != "common" && (startAll || shouldStart) {
|
|
|
+ if !startAll && !shouldStart {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ subSections := make(map[string]ini.Section)
|
|
|
+
|
|
|
+ if strings.HasPrefix(name, "range:") {
|
|
|
+ // range section
|
|
|
+ rangePrefix := strings.TrimSpace(strings.TrimPrefix(name, "range:"))
|
|
|
+ subSections, err = ParseRangeSection(rangePrefix, section)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ subSections[name] = section
|
|
|
+ }
|
|
|
+
|
|
|
+ for subName, subSection := range subSections {
|
|
|
// some proxy or visotr configure may be used this prefix
|
|
|
- section["prefix"] = prefix
|
|
|
- cfg, err := NewProxyConfFromFile(name, section)
|
|
|
+ subSection["prefix"] = prefix
|
|
|
+ cfg, err := NewProxyConfFromFile(subName, subSection)
|
|
|
if err != nil {
|
|
|
return proxyConfs, visitorConfs, err
|
|
|
}
|
|
|
|
|
|
- role := section["role"]
|
|
|
+ role := subSection["role"]
|
|
|
if role == "visitor" {
|
|
|
- visitorConfs[prefix+name] = cfg
|
|
|
+ visitorConfs[prefix+subName] = cfg
|
|
|
} else {
|
|
|
- proxyConfs[prefix+name] = cfg
|
|
|
+ proxyConfs[prefix+subName] = cfg
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
+func copySection(section ini.Section) (out ini.Section) {
|
|
|
+ out = make(ini.Section)
|
|
|
+ for k, v := range section {
|
|
|
+ out[k] = v
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|