add interface xnet.SrcAddr/DstAddr

This commit is contained in:
ginuerzh
2025-08-03 10:15:53 +08:00
parent 79203e407c
commit f71351f5ef
42 changed files with 518 additions and 295 deletions
+40 -20
View File
@@ -115,15 +115,34 @@ func BuildConfigFromCmd(serviceList, nodeList []string) (*config.Config, error)
}
if v := mdutil.GetString(md, "interface"); v != "" {
hopConfig.Interface = v
m["hop.interface"] = v
delete(m, "interface")
}
if v := mdutil.GetInt(md, "so_mark"); v > 0 {
hopConfig.SockOpts = &config.SockOptsConfig{
Mark: v,
}
m["hop.so_mark"] = v
delete(m, "so_mark")
}
if v := mdutil.GetInt(md, "proxyProtocol"); v > 0 {
m["hop.proxyProtocol"] = v
delete(m, "proxyProtocol")
}
hopMd := map[string]any{}
for k, v := range m {
if strings.HasPrefix(k, "node.") ||
strings.HasPrefix(k, "connector.") ||
strings.HasPrefix(k, "dialer.") {
continue
}
if s, found := strings.CutPrefix(k, "hop."); found {
hopMd[s] = v
delete(m, k)
continue
}
hopMd[k] = v
}
hopConfig.Metadata = hopMd
nodeConfig, err := buildNodeConfig(url, m)
if err != nil {
@@ -144,22 +163,6 @@ func BuildConfigFromCmd(serviceList, nodeList []string) (*config.Config, error)
}
hopConfig.Nodes = nodes
hopMd := map[string]any{}
for k, v := range m {
if strings.HasPrefix(k, "node.") ||
strings.HasPrefix(k, "connector.") ||
strings.HasPrefix(k, "dialer.") {
continue
}
if s, found := strings.CutPrefix(k, "hop."); found {
hopMd[s] = v
continue
}
hopMd[k] = v
}
hopConfig.Metadata = hopMd
chain.Hops = append(chain.Hops, hopConfig)
}
@@ -501,6 +504,23 @@ func buildServiceConfig(url *url.URL) ([]*config.ServiceConfig, error) {
m["service.interface"] = v
delete(m, "interface")
}
if v := mdutil.GetInt(md, "so_mark"); v > 0 {
m["service.so_mark"] = v
delete(m, "so_mark")
}
if v := mdutil.GetInt(md, "proxyProtocol"); v > 0 {
m["service.proxyProtocol"] = v
delete(m, "proxyProtocol")
}
if v := mdutil.GetString(md, "netns"); v != "" {
m["service.netns"] = v
delete(m, "netns")
}
if v := mdutil.GetString(md, "netns.out"); v != "" {
m["service.netns.out"] = v
delete(m, "netns.out")
}
selector := parseSelector(m)
serviceMd := map[string]any{}
+23 -18
View File
@@ -507,21 +507,23 @@ type ChainGroupConfig struct {
}
type HopConfig struct {
Name string `json:"name"`
Interface string `yaml:",omitempty" json:"interface,omitempty"`
SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,omitempty"`
Selector *SelectorConfig `yaml:",omitempty" json:"selector,omitempty"`
Bypass string `yaml:",omitempty" json:"bypass,omitempty"`
Bypasses []string `yaml:",omitempty" json:"bypasses,omitempty"`
Resolver string `yaml:",omitempty" json:"resolver,omitempty"`
Hosts string `yaml:",omitempty" json:"hosts,omitempty"`
Nodes []*NodeConfig `yaml:",omitempty" json:"nodes,omitempty"`
Reload time.Duration `yaml:",omitempty" json:"reload,omitempty"`
File *FileLoader `yaml:",omitempty" json:"file,omitempty"`
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
Metadata map[string]any `yaml:",omitempty" json:"metadata,omitempty"`
Name string `json:"name"`
// Deprecated: use metadata.interface instead
Interface string `yaml:",omitempty" json:"interface,omitempty"`
// Deprecated: use metadata.so_mark instead
SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,omitempty"`
Selector *SelectorConfig `yaml:",omitempty" json:"selector,omitempty"`
Bypass string `yaml:",omitempty" json:"bypass,omitempty"`
Bypasses []string `yaml:",omitempty" json:"bypasses,omitempty"`
Resolver string `yaml:",omitempty" json:"resolver,omitempty"`
Hosts string `yaml:",omitempty" json:"hosts,omitempty"`
Nodes []*NodeConfig `yaml:",omitempty" json:"nodes,omitempty"`
Reload time.Duration `yaml:",omitempty" json:"reload,omitempty"`
File *FileLoader `yaml:",omitempty" json:"file,omitempty"`
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
Metadata map[string]any `yaml:",omitempty" json:"metadata,omitempty"`
}
type NodeConfig struct {
@@ -534,9 +536,12 @@ type NodeConfig struct {
Hosts string `yaml:",omitempty" json:"hosts,omitempty"`
Connector *ConnectorConfig `yaml:",omitempty" json:"connector,omitempty"`
Dialer *DialerConfig `yaml:",omitempty" json:"dialer,omitempty"`
Interface string `yaml:",omitempty" json:"interface,omitempty"`
Netns string `yaml:",omitempty" json:"netns,omitempty"`
SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,omitempty"`
// Deprecated: use metadata.interface instead
Interface string `yaml:",omitempty" json:"interface,omitempty"`
// Deprecated: use metadata.netns instead
Netns string `yaml:",omitempty" json:"netns,omitempty"`
// Deprecated: use metadata.so_mark instead
SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,omitempty"`
// Deprecated: use matcher instead
Filter *NodeFilterConfig `yaml:",omitempty" json:"filter,omitempty"`
Matcher *NodeMatcherConfig `yaml:",omitempty" json:"matcher,omitempty"`
+52 -9
View File
@@ -50,6 +50,8 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) {
}
}
var ppv int
var soMark int
ifce := cfg.Interface
var netns string
if cfg.Metadata != nil {
@@ -57,7 +59,16 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) {
if v := mdutil.GetString(md, parsing.MDKeyInterface); v != "" {
ifce = v
}
netns = mdutil.GetString(md, "netns")
if cfg.SockOpts != nil {
soMark = cfg.SockOpts.Mark
}
if v := mdutil.GetInt(md, parsing.MDKeySoMark); v > 0 {
soMark = v
}
ppv = mdutil.GetInt(md, parsing.MDKeyProxyProtocol)
netns = mdutil.GetString(md, parsing.MDKeyNetns)
}
var nodes []*chain.Node
@@ -66,21 +77,53 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) {
continue
}
m := v.Metadata
if m == nil {
m = map[string]any{}
v.Metadata = m
}
md := metadata.NewMetadata(m)
if v.Resolver == "" {
v.Resolver = cfg.Resolver
}
if v.Hosts == "" {
v.Hosts = cfg.Hosts
}
if v.Interface == "" {
v.Interface = ifce
}
if v.Netns == "" {
v.Netns = netns
}
if v.SockOpts == nil {
v.SockOpts = cfg.SockOpts
if !md.IsExists(parsing.MDKeyInterface) {
// inherit from hop
if ifce != "" {
m[parsing.MDKeyInterface] = ifce
}
// node level
if v.Interface != "" {
m[parsing.MDKeyInterface] = v.Interface
}
}
if !md.IsExists(parsing.MDKeySoMark) {
// inherit from hop
if soMark != 0 {
m[parsing.MDKeySoMark] = soMark
}
// node level
if v.SockOpts != nil && v.SockOpts.Mark != 0 {
m[parsing.MDKeySoMark] = v.SockOpts.Mark
}
}
if !md.IsExists(parsing.MDKeyProxyProtocol) && ppv > 0 {
// inherit from hop
m[parsing.MDKeyProxyProtocol] = ppv
}
if !md.IsExists(parsing.MDKeyNetns) {
// inherit from hop
if netns != "" {
m[parsing.MDKeyNetns] = netns
}
// node level
if v.Netns != "" {
m[parsing.MDKeyNetns] = v.Name
}
}
if v.Connector == nil {
+8 -17
View File
@@ -10,7 +10,6 @@ import (
"github.com/go-gost/core/connector"
"github.com/go-gost/core/dialer"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/metadata"
xauth "github.com/go-gost/x/auth"
xbypass "github.com/go-gost/x/bypass"
xchain "github.com/go-gost/x/chain"
@@ -65,11 +64,6 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
return nil, err
}
var nm metadata.Metadata
if cfg.Metadata != nil {
nm = mdx.NewMetadata(cfg.Metadata)
}
connectorLogger := nodeLogger.WithFields(map[string]any{
"kind": "connector",
})
@@ -105,10 +99,7 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
return nil, err
}
var ppv int
if nm != nil {
ppv = mdutil.GetInt(nm, parsing.MDKeyProxyProtocol)
}
md := mdx.NewMetadata(cfg.Metadata)
dialerLogger := nodeLogger.WithFields(map[string]any{
"kind": "dialer",
@@ -120,7 +111,7 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
dialer.AuthOption(auth_parser.Info(cfg.Dialer.Auth)),
dialer.TLSConfigOption(tlsConfig),
dialer.LoggerOption(dialerLogger),
dialer.ProxyProtocolOption(ppv),
dialer.ProxyProtocolOption(mdutil.GetInt(md, parsing.MDKeyProxyProtocol)),
)
} else {
return nil, fmt.Errorf("unregistered dialer: %s", cfg.Dialer.Type)
@@ -135,16 +126,16 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
}
var sockOpts *chain.SockOpts
if cfg.SockOpts != nil {
if v := mdutil.GetInt(md, parsing.MDKeySoMark); v != 0 {
sockOpts = &chain.SockOpts{
Mark: cfg.SockOpts.Mark,
Mark: v,
}
}
tr := xchain.NewTransport(d, cr,
chain.AddrTransportOption(cfg.Addr),
chain.InterfaceTransportOption(cfg.Interface),
chain.NetnsTransportOption(cfg.Netns),
chain.InterfaceTransportOption(mdutil.GetString(md, parsing.MDKeyInterface)),
chain.NetnsTransportOption(mdutil.GetString(md, parsing.MDKeyNetns)),
chain.SockOptsTransportOption(sockOpts),
)
@@ -153,7 +144,7 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
chain.BypassNodeOption(xbypass.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.MetadataNodeOption(md),
chain.NetworkNodeOption(cfg.Network),
}
@@ -219,7 +210,7 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
rewriteURL := cfg.HTTP.RewriteURL
if rewriteURL == nil {
rewriteURL = cfg.HTTP.Rewrite
}
}
for _, v := range rewriteURL {
if pattern, _ := regexp.Compile(v.Match); pattern != nil {
settings.RewriteURL = append(settings.RewriteURL, chain.HTTPURLRewriteSetting{