140 lines
2.6 KiB
Go
140 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/go-gost/gost/pkg/config"
|
|
"github.com/go-gost/gost/pkg/registry"
|
|
)
|
|
|
|
// normConfig normalizes the config.
|
|
func normConfig(cfg *config.Config) {
|
|
for _, svc := range cfg.Services {
|
|
normService(svc)
|
|
}
|
|
for _, chain := range cfg.Chains {
|
|
normChain(chain)
|
|
}
|
|
}
|
|
|
|
func normService(svc *config.ServiceConfig) {
|
|
if svc.URL == "" {
|
|
return
|
|
}
|
|
|
|
u, _ := url.Parse(svc.URL)
|
|
|
|
var handler, listener string
|
|
schemes := strings.Split(u.Scheme, "+")
|
|
if len(schemes) == 1 {
|
|
handler = schemes[0]
|
|
listener = schemes[0]
|
|
}
|
|
if len(schemes) == 2 {
|
|
handler = schemes[0]
|
|
listener = schemes[1]
|
|
}
|
|
|
|
md := make(map[string]interface{})
|
|
for k, v := range u.Query() {
|
|
if len(v) > 0 {
|
|
md[k] = v[0]
|
|
}
|
|
}
|
|
if u.User != nil {
|
|
md["users"] = []interface{}{u.User.String()}
|
|
}
|
|
|
|
svc.Addr = u.Host
|
|
|
|
if h := registry.GetHandler(handler); h == nil {
|
|
handler = "auto"
|
|
}
|
|
if ln := registry.GetListener(listener); ln == nil {
|
|
listener = "tcp"
|
|
if handler == "ssu" {
|
|
listener = "udp"
|
|
}
|
|
}
|
|
|
|
if remotes := strings.Trim(u.EscapedPath(), "/"); remotes != "" {
|
|
svc.Forwarder = &config.ForwarderConfig{
|
|
Targets: strings.Split(remotes, ","),
|
|
}
|
|
if handler != "relay" {
|
|
if listener == "tcp" || listener == "udp" ||
|
|
listener == "rtcp" || listener == "rudp" ||
|
|
listener == "tun" || listener == "tap" {
|
|
handler = listener
|
|
} else {
|
|
handler = "tcp"
|
|
}
|
|
}
|
|
}
|
|
|
|
svc.Handler = &config.HandlerConfig{
|
|
Type: handler,
|
|
Metadata: md,
|
|
}
|
|
svc.Listener = &config.ListenerConfig{
|
|
Type: listener,
|
|
Metadata: md,
|
|
}
|
|
}
|
|
|
|
func normChain(chain *config.ChainConfig) {
|
|
for _, hop := range chain.Hops {
|
|
for _, node := range hop.Nodes {
|
|
if node.URL == "" {
|
|
continue
|
|
}
|
|
|
|
u, _ := url.Parse(node.URL)
|
|
|
|
var connector, dialer string
|
|
schemes := strings.Split(u.Scheme, "+")
|
|
if len(schemes) == 1 {
|
|
connector = schemes[0]
|
|
dialer = schemes[0]
|
|
}
|
|
if len(schemes) == 2 {
|
|
connector = schemes[0]
|
|
dialer = schemes[1]
|
|
}
|
|
|
|
md := make(map[string]interface{})
|
|
for k, v := range u.Query() {
|
|
if len(v) > 0 {
|
|
md[k] = v[0]
|
|
}
|
|
}
|
|
if u.User != nil {
|
|
md["user"] = u.User.String()
|
|
}
|
|
md["serverName"] = u.Host
|
|
|
|
node.Addr = u.Host
|
|
|
|
if c := registry.GetConnector(connector); c == nil {
|
|
connector = "http"
|
|
}
|
|
if d := registry.GetDialer(dialer); d == nil {
|
|
dialer = "tcp"
|
|
if connector == "ssu" {
|
|
dialer = "udp"
|
|
}
|
|
}
|
|
|
|
node.Connector = &config.ConnectorConfig{
|
|
Type: connector,
|
|
Metadata: md,
|
|
}
|
|
node.Dialer = &config.DialerConfig{
|
|
Type: dialer,
|
|
Metadata: md,
|
|
}
|
|
}
|
|
}
|
|
}
|