add reload and plugin support for hop
This commit is contained in:
198
config/parsing/node/parse.go
Normal file
198
config/parsing/node/parse.go
Normal file
@ -0,0 +1,198 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-gost/core/bypass"
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/connector"
|
||||
"github.com/go-gost/core/dialer"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/core/metadata"
|
||||
mdutil "github.com/go-gost/core/metadata/util"
|
||||
xauth "github.com/go-gost/x/auth"
|
||||
"github.com/go-gost/x/config"
|
||||
"github.com/go-gost/x/config/parsing"
|
||||
auth_parser "github.com/go-gost/x/config/parsing/auth"
|
||||
bypass_parser "github.com/go-gost/x/config/parsing/bypass"
|
||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||
mdx "github.com/go-gost/x/metadata"
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
|
||||
func ParseNode(hop string, cfg *config.NodeConfig) (*chain.Node, error) {
|
||||
if cfg == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if cfg.Connector == nil {
|
||||
cfg.Connector = &config.ConnectorConfig{
|
||||
Type: "http",
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.Dialer == nil {
|
||||
cfg.Dialer = &config.DialerConfig{
|
||||
Type: "tcp",
|
||||
}
|
||||
}
|
||||
|
||||
nodeLogger := logger.Default().WithFields(map[string]any{
|
||||
"hop": hop,
|
||||
"kind": "node",
|
||||
"node": cfg.Name,
|
||||
"connector": cfg.Connector.Type,
|
||||
"dialer": cfg.Dialer.Type,
|
||||
})
|
||||
|
||||
serverName, _, _ := net.SplitHostPort(cfg.Addr)
|
||||
|
||||
tlsCfg := cfg.Connector.TLS
|
||||
if tlsCfg == nil {
|
||||
tlsCfg = &config.TLSConfig{}
|
||||
}
|
||||
if tlsCfg.ServerName == "" {
|
||||
tlsCfg.ServerName = serverName
|
||||
}
|
||||
tlsConfig, err := tls_util.LoadClientConfig(
|
||||
tlsCfg.CertFile, tlsCfg.KeyFile, tlsCfg.CAFile,
|
||||
tlsCfg.Secure, tlsCfg.ServerName)
|
||||
if err != nil {
|
||||
nodeLogger.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var nm metadata.Metadata
|
||||
if cfg.Metadata != nil {
|
||||
nm = mdx.NewMetadata(cfg.Metadata)
|
||||
}
|
||||
|
||||
connectorLogger := nodeLogger.WithFields(map[string]any{
|
||||
"kind": "connector",
|
||||
})
|
||||
var cr connector.Connector
|
||||
if rf := registry.ConnectorRegistry().Get(cfg.Connector.Type); rf != nil {
|
||||
cr = rf(
|
||||
connector.AuthOption(auth_parser.Info(cfg.Connector.Auth)),
|
||||
connector.TLSConfigOption(tlsConfig),
|
||||
connector.LoggerOption(connectorLogger),
|
||||
)
|
||||
} else {
|
||||
return nil, fmt.Errorf("unregistered connector: %s", cfg.Connector.Type)
|
||||
}
|
||||
|
||||
if cfg.Connector.Metadata == nil {
|
||||
cfg.Connector.Metadata = make(map[string]any)
|
||||
}
|
||||
if err := cr.Init(mdx.NewMetadata(cfg.Connector.Metadata)); err != nil {
|
||||
connectorLogger.Error("init: ", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsCfg = cfg.Dialer.TLS
|
||||
if tlsCfg == nil {
|
||||
tlsCfg = &config.TLSConfig{}
|
||||
}
|
||||
if tlsCfg.ServerName == "" {
|
||||
tlsCfg.ServerName = serverName
|
||||
}
|
||||
tlsConfig, err = tls_util.LoadClientConfig(
|
||||
tlsCfg.CertFile, tlsCfg.KeyFile, tlsCfg.CAFile,
|
||||
tlsCfg.Secure, tlsCfg.ServerName)
|
||||
if err != nil {
|
||||
nodeLogger.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ppv int
|
||||
if nm != nil {
|
||||
ppv = mdutil.GetInt(nm, parsing.MDKeyProxyProtocol)
|
||||
}
|
||||
|
||||
dialerLogger := nodeLogger.WithFields(map[string]any{
|
||||
"kind": "dialer",
|
||||
})
|
||||
|
||||
var d dialer.Dialer
|
||||
if rf := registry.DialerRegistry().Get(cfg.Dialer.Type); rf != nil {
|
||||
d = rf(
|
||||
dialer.AuthOption(auth_parser.Info(cfg.Dialer.Auth)),
|
||||
dialer.TLSConfigOption(tlsConfig),
|
||||
dialer.LoggerOption(dialerLogger),
|
||||
dialer.ProxyProtocolOption(ppv),
|
||||
)
|
||||
} else {
|
||||
return nil, fmt.Errorf("unregistered dialer: %s", cfg.Dialer.Type)
|
||||
}
|
||||
|
||||
if cfg.Dialer.Metadata == nil {
|
||||
cfg.Dialer.Metadata = make(map[string]any)
|
||||
}
|
||||
if err := d.Init(mdx.NewMetadata(cfg.Dialer.Metadata)); err != nil {
|
||||
dialerLogger.Error("init: ", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sockOpts *chain.SockOpts
|
||||
if cfg.SockOpts != nil {
|
||||
sockOpts = &chain.SockOpts{
|
||||
Mark: cfg.SockOpts.Mark,
|
||||
}
|
||||
}
|
||||
|
||||
tr := chain.NewTransport(d, cr,
|
||||
chain.AddrTransportOption(cfg.Addr),
|
||||
chain.InterfaceTransportOption(cfg.Interface),
|
||||
chain.SockOptsTransportOption(sockOpts),
|
||||
chain.TimeoutTransportOption(10*time.Second),
|
||||
)
|
||||
|
||||
// convert *.example.com to .example.com
|
||||
// convert *example.com to example.com
|
||||
host := cfg.Host
|
||||
if strings.HasPrefix(host, "*") {
|
||||
host = host[1:]
|
||||
if !strings.HasPrefix(host, ".") {
|
||||
host = "." + host
|
||||
}
|
||||
}
|
||||
|
||||
opts := []chain.NodeOption{
|
||||
chain.TransportNodeOption(tr),
|
||||
chain.BypassNodeOption(bypass.BypassGroup(bypass_parser.List(cfg.Bypass, cfg.Bypasses...)...)),
|
||||
chain.ResoloverNodeOption(registry.ResolverRegistry().Get(cfg.Resolver)),
|
||||
chain.HostMapperNodeOption(registry.HostsRegistry().Get(cfg.Hosts)),
|
||||
chain.MetadataNodeOption(nm),
|
||||
chain.HostNodeOption(host),
|
||||
chain.ProtocolNodeOption(cfg.Protocol),
|
||||
}
|
||||
if cfg.HTTP != nil {
|
||||
opts = append(opts, chain.HTTPNodeOption(&chain.HTTPNodeSettings{
|
||||
Host: cfg.HTTP.Host,
|
||||
Header: cfg.HTTP.Header,
|
||||
}))
|
||||
}
|
||||
if cfg.TLS != nil {
|
||||
opts = append(opts, chain.TLSNodeOption(&chain.TLSNodeSettings{
|
||||
ServerName: cfg.TLS.ServerName,
|
||||
Secure: cfg.TLS.Secure,
|
||||
}))
|
||||
}
|
||||
if cfg.Auth != nil {
|
||||
opts = append(opts, chain.AutherNodeOption(
|
||||
xauth.NewAuthenticator(
|
||||
xauth.AuthsOption(map[string]string{cfg.Auth.Username: cfg.Auth.Password}),
|
||||
xauth.LoggerOption(logger.Default().WithFields(map[string]any{
|
||||
"kind": "node",
|
||||
"node": cfg.Name,
|
||||
"addr": cfg.Addr,
|
||||
"host": cfg.Host,
|
||||
"protocol": cfg.Protocol,
|
||||
})),
|
||||
)))
|
||||
}
|
||||
return chain.NewNode(cfg.Name, cfg.Addr, opts...), nil
|
||||
}
|
Reference in New Issue
Block a user