add interface xnet.SrcAddr/DstAddr
This commit is contained in:
@@ -58,6 +58,20 @@ func (c *serverConn) Metadata() metadata.Metadata {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *serverConn) SrcAddr() net.Addr {
|
||||||
|
if sc, ok := c.Conn.(xnet.SrcAddr); ok {
|
||||||
|
return sc.SrcAddr()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *serverConn) DstAddr() net.Addr {
|
||||||
|
if sc, ok := c.Conn.(xnet.DstAddr); ok {
|
||||||
|
return sc.DstAddr()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *serverConn) CloseRead() error {
|
func (c *serverConn) CloseRead() error {
|
||||||
if sc, ok := c.Conn.(xio.CloseRead); ok {
|
if sc, ok := c.Conn.(xio.CloseRead); ok {
|
||||||
return sc.CloseRead()
|
return sc.CloseRead()
|
||||||
|
|||||||
+5
-1
@@ -51,11 +51,15 @@ func (p *grpcPlugin) Authenticate(ctx context.Context, user, password string, op
|
|||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var clientAddr string
|
||||||
|
if v := ctxvalue.SrcAddrFromContext(ctx); v != nil {
|
||||||
|
clientAddr = v.String()
|
||||||
|
}
|
||||||
r, err := p.client.Authenticate(ctx,
|
r, err := p.client.Authenticate(ctx,
|
||||||
&proto.AuthenticateRequest{
|
&proto.AuthenticateRequest{
|
||||||
Username: user,
|
Username: user,
|
||||||
Password: password,
|
Password: password,
|
||||||
Client: string(ctxvalue.ClientAddrFromContext(ctx)),
|
Client: clientAddr,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error(err)
|
p.log.Error(err)
|
||||||
|
|||||||
+6
-1
@@ -53,10 +53,15 @@ func (p *httpPlugin) Authenticate(ctx context.Context, user, password string, op
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var clientAddr string
|
||||||
|
if v := ctxvalue.SrcAddrFromContext(ctx); v != nil {
|
||||||
|
clientAddr = v.String()
|
||||||
|
}
|
||||||
|
|
||||||
rb := httpPluginRequest{
|
rb := httpPluginRequest{
|
||||||
Username: user,
|
Username: user,
|
||||||
Password: password,
|
Password: password,
|
||||||
Client: string(ctxvalue.ClientAddrFromContext(ctx)),
|
Client: clientAddr,
|
||||||
}
|
}
|
||||||
v, err := json.Marshal(&rb)
|
v, err := json.Marshal(&rb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+40
-20
@@ -115,15 +115,34 @@ func BuildConfigFromCmd(serviceList, nodeList []string) (*config.Config, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if v := mdutil.GetString(md, "interface"); v != "" {
|
if v := mdutil.GetString(md, "interface"); v != "" {
|
||||||
hopConfig.Interface = v
|
m["hop.interface"] = v
|
||||||
delete(m, "interface")
|
delete(m, "interface")
|
||||||
}
|
}
|
||||||
if v := mdutil.GetInt(md, "so_mark"); v > 0 {
|
if v := mdutil.GetInt(md, "so_mark"); v > 0 {
|
||||||
hopConfig.SockOpts = &config.SockOptsConfig{
|
m["hop.so_mark"] = v
|
||||||
Mark: v,
|
|
||||||
}
|
|
||||||
delete(m, "so_mark")
|
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)
|
nodeConfig, err := buildNodeConfig(url, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -144,22 +163,6 @@ func BuildConfigFromCmd(serviceList, nodeList []string) (*config.Config, error)
|
|||||||
}
|
}
|
||||||
hopConfig.Nodes = nodes
|
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)
|
chain.Hops = append(chain.Hops, hopConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,6 +504,23 @@ func buildServiceConfig(url *url.URL) ([]*config.ServiceConfig, error) {
|
|||||||
m["service.interface"] = v
|
m["service.interface"] = v
|
||||||
delete(m, "interface")
|
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)
|
selector := parseSelector(m)
|
||||||
|
|
||||||
serviceMd := map[string]any{}
|
serviceMd := map[string]any{}
|
||||||
|
|||||||
+23
-18
@@ -507,21 +507,23 @@ type ChainGroupConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type HopConfig struct {
|
type HopConfig struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Interface string `yaml:",omitempty" json:"interface,omitempty"`
|
// Deprecated: use metadata.interface instead
|
||||||
SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,omitempty"`
|
Interface string `yaml:",omitempty" json:"interface,omitempty"`
|
||||||
Selector *SelectorConfig `yaml:",omitempty" json:"selector,omitempty"`
|
// Deprecated: use metadata.so_mark instead
|
||||||
Bypass string `yaml:",omitempty" json:"bypass,omitempty"`
|
SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,omitempty"`
|
||||||
Bypasses []string `yaml:",omitempty" json:"bypasses,omitempty"`
|
Selector *SelectorConfig `yaml:",omitempty" json:"selector,omitempty"`
|
||||||
Resolver string `yaml:",omitempty" json:"resolver,omitempty"`
|
Bypass string `yaml:",omitempty" json:"bypass,omitempty"`
|
||||||
Hosts string `yaml:",omitempty" json:"hosts,omitempty"`
|
Bypasses []string `yaml:",omitempty" json:"bypasses,omitempty"`
|
||||||
Nodes []*NodeConfig `yaml:",omitempty" json:"nodes,omitempty"`
|
Resolver string `yaml:",omitempty" json:"resolver,omitempty"`
|
||||||
Reload time.Duration `yaml:",omitempty" json:"reload,omitempty"`
|
Hosts string `yaml:",omitempty" json:"hosts,omitempty"`
|
||||||
File *FileLoader `yaml:",omitempty" json:"file,omitempty"`
|
Nodes []*NodeConfig `yaml:",omitempty" json:"nodes,omitempty"`
|
||||||
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
|
Reload time.Duration `yaml:",omitempty" json:"reload,omitempty"`
|
||||||
HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"`
|
File *FileLoader `yaml:",omitempty" json:"file,omitempty"`
|
||||||
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
|
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
|
||||||
Metadata map[string]any `yaml:",omitempty" json:"metadata,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 {
|
type NodeConfig struct {
|
||||||
@@ -534,9 +536,12 @@ type NodeConfig struct {
|
|||||||
Hosts string `yaml:",omitempty" json:"hosts,omitempty"`
|
Hosts string `yaml:",omitempty" json:"hosts,omitempty"`
|
||||||
Connector *ConnectorConfig `yaml:",omitempty" json:"connector,omitempty"`
|
Connector *ConnectorConfig `yaml:",omitempty" json:"connector,omitempty"`
|
||||||
Dialer *DialerConfig `yaml:",omitempty" json:"dialer,omitempty"`
|
Dialer *DialerConfig `yaml:",omitempty" json:"dialer,omitempty"`
|
||||||
Interface string `yaml:",omitempty" json:"interface,omitempty"`
|
// Deprecated: use metadata.interface instead
|
||||||
Netns string `yaml:",omitempty" json:"netns,omitempty"`
|
Interface string `yaml:",omitempty" json:"interface,omitempty"`
|
||||||
SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,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
|
// Deprecated: use matcher instead
|
||||||
Filter *NodeFilterConfig `yaml:",omitempty" json:"filter,omitempty"`
|
Filter *NodeFilterConfig `yaml:",omitempty" json:"filter,omitempty"`
|
||||||
Matcher *NodeMatcherConfig `yaml:",omitempty" json:"matcher,omitempty"`
|
Matcher *NodeMatcherConfig `yaml:",omitempty" json:"matcher,omitempty"`
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ppv int
|
||||||
|
var soMark int
|
||||||
ifce := cfg.Interface
|
ifce := cfg.Interface
|
||||||
var netns string
|
var netns string
|
||||||
if cfg.Metadata != nil {
|
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 != "" {
|
if v := mdutil.GetString(md, parsing.MDKeyInterface); v != "" {
|
||||||
ifce = 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
|
var nodes []*chain.Node
|
||||||
@@ -66,21 +77,53 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m := v.Metadata
|
||||||
|
if m == nil {
|
||||||
|
m = map[string]any{}
|
||||||
|
v.Metadata = m
|
||||||
|
}
|
||||||
|
md := metadata.NewMetadata(m)
|
||||||
|
|
||||||
if v.Resolver == "" {
|
if v.Resolver == "" {
|
||||||
v.Resolver = cfg.Resolver
|
v.Resolver = cfg.Resolver
|
||||||
}
|
}
|
||||||
if v.Hosts == "" {
|
if v.Hosts == "" {
|
||||||
v.Hosts = cfg.Hosts
|
v.Hosts = cfg.Hosts
|
||||||
}
|
}
|
||||||
if v.Interface == "" {
|
|
||||||
v.Interface = ifce
|
|
||||||
}
|
|
||||||
if v.Netns == "" {
|
|
||||||
v.Netns = netns
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.SockOpts == nil {
|
if !md.IsExists(parsing.MDKeyInterface) {
|
||||||
v.SockOpts = cfg.SockOpts
|
// 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 {
|
if v.Connector == nil {
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/go-gost/core/connector"
|
"github.com/go-gost/core/connector"
|
||||||
"github.com/go-gost/core/dialer"
|
"github.com/go-gost/core/dialer"
|
||||||
"github.com/go-gost/core/logger"
|
"github.com/go-gost/core/logger"
|
||||||
"github.com/go-gost/core/metadata"
|
|
||||||
xauth "github.com/go-gost/x/auth"
|
xauth "github.com/go-gost/x/auth"
|
||||||
xbypass "github.com/go-gost/x/bypass"
|
xbypass "github.com/go-gost/x/bypass"
|
||||||
xchain "github.com/go-gost/x/chain"
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var nm metadata.Metadata
|
|
||||||
if cfg.Metadata != nil {
|
|
||||||
nm = mdx.NewMetadata(cfg.Metadata)
|
|
||||||
}
|
|
||||||
|
|
||||||
connectorLogger := nodeLogger.WithFields(map[string]any{
|
connectorLogger := nodeLogger.WithFields(map[string]any{
|
||||||
"kind": "connector",
|
"kind": "connector",
|
||||||
})
|
})
|
||||||
@@ -105,10 +99,7 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var ppv int
|
md := mdx.NewMetadata(cfg.Metadata)
|
||||||
if nm != nil {
|
|
||||||
ppv = mdutil.GetInt(nm, parsing.MDKeyProxyProtocol)
|
|
||||||
}
|
|
||||||
|
|
||||||
dialerLogger := nodeLogger.WithFields(map[string]any{
|
dialerLogger := nodeLogger.WithFields(map[string]any{
|
||||||
"kind": "dialer",
|
"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.AuthOption(auth_parser.Info(cfg.Dialer.Auth)),
|
||||||
dialer.TLSConfigOption(tlsConfig),
|
dialer.TLSConfigOption(tlsConfig),
|
||||||
dialer.LoggerOption(dialerLogger),
|
dialer.LoggerOption(dialerLogger),
|
||||||
dialer.ProxyProtocolOption(ppv),
|
dialer.ProxyProtocolOption(mdutil.GetInt(md, parsing.MDKeyProxyProtocol)),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("unregistered dialer: %s", cfg.Dialer.Type)
|
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
|
var sockOpts *chain.SockOpts
|
||||||
if cfg.SockOpts != nil {
|
if v := mdutil.GetInt(md, parsing.MDKeySoMark); v != 0 {
|
||||||
sockOpts = &chain.SockOpts{
|
sockOpts = &chain.SockOpts{
|
||||||
Mark: cfg.SockOpts.Mark,
|
Mark: v,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tr := xchain.NewTransport(d, cr,
|
tr := xchain.NewTransport(d, cr,
|
||||||
chain.AddrTransportOption(cfg.Addr),
|
chain.AddrTransportOption(cfg.Addr),
|
||||||
chain.InterfaceTransportOption(cfg.Interface),
|
chain.InterfaceTransportOption(mdutil.GetString(md, parsing.MDKeyInterface)),
|
||||||
chain.NetnsTransportOption(cfg.Netns),
|
chain.NetnsTransportOption(mdutil.GetString(md, parsing.MDKeyNetns)),
|
||||||
chain.SockOptsTransportOption(sockOpts),
|
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.BypassNodeOption(xbypass.BypassGroup(bypass_parser.List(cfg.Bypass, cfg.Bypasses...)...)),
|
||||||
chain.ResoloverNodeOption(registry.ResolverRegistry().Get(cfg.Resolver)),
|
chain.ResoloverNodeOption(registry.ResolverRegistry().Get(cfg.Resolver)),
|
||||||
chain.HostMapperNodeOption(registry.HostsRegistry().Get(cfg.Hosts)),
|
chain.HostMapperNodeOption(registry.HostsRegistry().Get(cfg.Hosts)),
|
||||||
chain.MetadataNodeOption(nm),
|
chain.MetadataNodeOption(md),
|
||||||
chain.NetworkNodeOption(cfg.Network),
|
chain.NetworkNodeOption(cfg.Network),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +210,7 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
|
|||||||
rewriteURL := cfg.HTTP.RewriteURL
|
rewriteURL := cfg.HTTP.RewriteURL
|
||||||
if rewriteURL == nil {
|
if rewriteURL == nil {
|
||||||
rewriteURL = cfg.HTTP.Rewrite
|
rewriteURL = cfg.HTTP.Rewrite
|
||||||
}
|
}
|
||||||
for _, v := range rewriteURL {
|
for _, v := range rewriteURL {
|
||||||
if pattern, _ := regexp.Compile(v.Match); pattern != nil {
|
if pattern, _ := regexp.Compile(v.Match); pattern != nil {
|
||||||
settings.RewriteURL = append(settings.RewriteURL, chain.HTTPURLRewriteSetting{
|
settings.RewriteURL = append(settings.RewriteURL, chain.HTTPURLRewriteSetting{
|
||||||
|
|||||||
@@ -77,9 +77,9 @@ func (c *routerConnector) Connect(ctx context.Context, conn net.Conn, network, a
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
srcAddr := conn.LocalAddr().String()
|
srcAddr := conn.RemoteAddr().String()
|
||||||
if v := ctxvalue.ClientAddrFromContext(ctx); v != "" {
|
if v := ctxvalue.SrcAddrFromContext(ctx); v != nil {
|
||||||
srcAddr = string(v)
|
srcAddr = v.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
af := &relay.AddrFeature{}
|
af := &relay.AddrFeature{}
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ func (c *tunnelConnector) Connect(ctx context.Context, conn net.Conn, network, a
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
srcAddr := conn.LocalAddr().String()
|
srcAddr := conn.RemoteAddr().String()
|
||||||
if v := ctxvalue.ClientAddrFromContext(ctx); v != "" {
|
if v := ctxvalue.SrcAddrFromContext(ctx); v != nil {
|
||||||
srcAddr = string(v)
|
srcAddr = v.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
af := &relay.AddrFeature{}
|
af := &relay.AddrFeature{}
|
||||||
|
|||||||
+60
-16
@@ -3,18 +3,21 @@ package ctx
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"net"
|
||||||
|
|
||||||
"github.com/go-gost/core/logger"
|
"github.com/go-gost/core/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ClientAddr string
|
||||||
|
|
||||||
|
func (a ClientAddr) String() string {
|
||||||
|
return string(a)
|
||||||
|
}
|
||||||
|
|
||||||
// clientAddrKey saves the client address.
|
// clientAddrKey saves the client address.
|
||||||
type clientAddrKey struct{}
|
type clientAddrKey struct{}
|
||||||
|
|
||||||
type ClientAddr string
|
var keyClientAddr clientAddrKey
|
||||||
|
|
||||||
var (
|
|
||||||
keyClientAddr clientAddrKey
|
|
||||||
)
|
|
||||||
|
|
||||||
func ContextWithClientAddr(ctx context.Context, addr ClientAddr) context.Context {
|
func ContextWithClientAddr(ctx context.Context, addr ClientAddr) context.Context {
|
||||||
return context.WithValue(ctx, keyClientAddr, addr)
|
return context.WithValue(ctx, keyClientAddr, addr)
|
||||||
@@ -25,9 +28,43 @@ func ClientAddrFromContext(ctx context.Context) ClientAddr {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// sidKey saves the session ID.
|
type (
|
||||||
type sidKey struct{}
|
srcAddrKey struct{}
|
||||||
type Sid string
|
dstAddrKey struct{}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
keySrcAddr srcAddrKey
|
||||||
|
keyDstAddr dstAddrKey
|
||||||
|
)
|
||||||
|
|
||||||
|
func ContextWithSrcAddr(ctx context.Context, addr net.Addr) context.Context {
|
||||||
|
return context.WithValue(ctx, keySrcAddr, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SrcAddrFromContext(ctx context.Context) net.Addr {
|
||||||
|
v, _ := ctx.Value(keySrcAddr).(net.Addr)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func ContextWithDstAddr(ctx context.Context, addr net.Addr) context.Context {
|
||||||
|
return context.WithValue(ctx, keyDstAddr, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DstAddrFromContext(ctx context.Context) net.Addr {
|
||||||
|
v, _ := ctx.Value(keyDstAddr).(net.Addr)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
Sid string
|
||||||
|
// sidKey saves the session ID.
|
||||||
|
sidKey struct{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s Sid) String() string {
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
keySid sidKey
|
keySid sidKey
|
||||||
@@ -42,12 +79,13 @@ func SidFromContext(ctx context.Context) Sid {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// hashKey saves the hash source for Selector.
|
type (
|
||||||
type hashKey struct{}
|
// hashKey saves the hash source for Selector.
|
||||||
|
hashKey struct{}
|
||||||
type Hash struct {
|
Hash struct {
|
||||||
Source string
|
Source string
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
clientHashKey = &hashKey{}
|
clientHashKey = &hashKey{}
|
||||||
@@ -64,8 +102,14 @@ func HashFromContext(ctx context.Context) *Hash {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type clientIDKey struct{}
|
type (
|
||||||
type ClientID string
|
ClientID string
|
||||||
|
clientIDKey struct{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s ClientID) String() string {
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
keyClientID = &clientIDKey{}
|
keyClientID = &clientIDKey{}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module github.com/go-gost/x
|
module github.com/go-gost/x
|
||||||
|
|
||||||
go 1.23.1
|
go 1.24
|
||||||
|
|
||||||
toolchain go1.24.5
|
toolchain go1.24.5
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ require (
|
|||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pion/dtls/v2 v2.2.6
|
github.com/pion/dtls/v2 v2.2.6
|
||||||
github.com/pires/go-proxyproto v0.7.0
|
github.com/pires/go-proxyproto v0.8.1
|
||||||
github.com/prometheus/client_golang v1.19.1
|
github.com/prometheus/client_golang v1.19.1
|
||||||
github.com/quic-go/quic-go v0.53.0
|
github.com/quic-go/quic-go v0.53.0
|
||||||
github.com/quic-go/webtransport-go v0.9.0
|
github.com/quic-go/webtransport-go v0.9.0
|
||||||
|
|||||||
@@ -162,6 +162,8 @@ github.com/pion/udp/v2 v2.0.1 h1:xP0z6WNux1zWEjhC7onRA3EwwSliXqu1ElUZAQhUP54=
|
|||||||
github.com/pion/udp/v2 v2.0.1/go.mod h1:B7uvTMP00lzWdyMr/1PVZXtV3wpPIxBRd4Wl6AksXn8=
|
github.com/pion/udp/v2 v2.0.1/go.mod h1:B7uvTMP00lzWdyMr/1PVZXtV3wpPIxBRd4Wl6AksXn8=
|
||||||
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
|
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
|
||||||
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
|
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
|
||||||
|
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
|
||||||
|
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
|||||||
@@ -148,12 +148,8 @@ func (h *dnsHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
|
|||||||
SID: string(ctxvalue.SidFromContext(ctx)),
|
SID: string(ctxvalue.SidFromContext(ctx)),
|
||||||
}
|
}
|
||||||
|
|
||||||
ro.ClientIP = conn.RemoteAddr().String()
|
if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil {
|
||||||
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
ro.ClientIP = srcAddr.String()
|
||||||
ro.ClientIP = string(clientAddr)
|
|
||||||
}
|
|
||||||
if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" {
|
|
||||||
ro.ClientIP = h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/go-gost/core/handler"
|
"github.com/go-gost/core/handler"
|
||||||
md "github.com/go-gost/core/metadata"
|
md "github.com/go-gost/core/metadata"
|
||||||
"github.com/go-gost/core/recorder"
|
"github.com/go-gost/core/recorder"
|
||||||
|
ctxvalue "github.com/go-gost/x/ctx"
|
||||||
xrecorder "github.com/go-gost/x/recorder"
|
xrecorder "github.com/go-gost/x/recorder"
|
||||||
"github.com/go-gost/x/registry"
|
"github.com/go-gost/x/registry"
|
||||||
)
|
)
|
||||||
@@ -65,7 +66,13 @@ func (h *fileHandler) Init(md md.Metadata) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *fileHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.HandleOption) error {
|
func (h *fileHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.HandleOption) error {
|
||||||
|
var clientAddr string
|
||||||
|
if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil {
|
||||||
|
clientAddr = srcAddr.String()
|
||||||
|
}
|
||||||
|
|
||||||
h.options.Logger.WithFields(map[string]any{
|
h.options.Logger.WithFields(map[string]any{
|
||||||
|
"client": clientAddr,
|
||||||
"remote": conn.RemoteAddr().String(),
|
"remote": conn.RemoteAddr().String(),
|
||||||
"local": conn.LocalAddr().String(),
|
"local": conn.LocalAddr().String(),
|
||||||
}).Infof("%s - %s", conn.RemoteAddr(), conn.LocalAddr())
|
}).Infof("%s - %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||||
@@ -101,7 +108,6 @@ func (h *fileHandler) handleFunc(w http.ResponseWriter, r *http.Request) {
|
|||||||
},
|
},
|
||||||
Time: start,
|
Time: start,
|
||||||
}
|
}
|
||||||
ro.ClientIP, _, _ = net.SplitHostPort(r.RemoteAddr)
|
|
||||||
|
|
||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
"remote": r.RemoteAddr,
|
"remote": r.RemoteAddr,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/go-gost/core/recorder"
|
"github.com/go-gost/core/recorder"
|
||||||
ctxvalue "github.com/go-gost/x/ctx"
|
ctxvalue "github.com/go-gost/x/ctx"
|
||||||
xnet "github.com/go-gost/x/internal/net"
|
xnet "github.com/go-gost/x/internal/net"
|
||||||
|
"github.com/go-gost/x/internal/net/proxyproto"
|
||||||
"github.com/go-gost/x/internal/util/forwarder"
|
"github.com/go-gost/x/internal/util/forwarder"
|
||||||
"github.com/go-gost/x/internal/util/sniffing"
|
"github.com/go-gost/x/internal/util/sniffing"
|
||||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||||
@@ -89,22 +90,16 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
SID: string(ctxvalue.SidFromContext(ctx)),
|
SID: string(ctxvalue.SidFromContext(ctx)),
|
||||||
}
|
}
|
||||||
|
|
||||||
ro.ClientIP = conn.RemoteAddr().String()
|
if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil {
|
||||||
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
ro.ClientIP = srcAddr.String()
|
||||||
ro.ClientIP = string(clientAddr)
|
|
||||||
} else {
|
|
||||||
ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(conn.RemoteAddr().String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" {
|
|
||||||
ro.ClientIP = h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
"remote": conn.RemoteAddr().String(),
|
"network": ro.Network,
|
||||||
"local": conn.LocalAddr().String(),
|
"remote": conn.RemoteAddr().String(),
|
||||||
"sid": ro.SID,
|
"local": conn.LocalAddr().String(),
|
||||||
"client": ro.ClientIP,
|
"sid": ro.SID,
|
||||||
|
"client": ro.ClientIP,
|
||||||
})
|
})
|
||||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||||
|
|
||||||
@@ -157,6 +152,13 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address)
|
cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address)
|
||||||
ro.Route = buf.String()
|
ro.Route = buf.String()
|
||||||
|
|
||||||
|
cc = proxyproto.WrapClientConn(
|
||||||
|
h.md.proxyProtocol,
|
||||||
|
ctxvalue.SrcAddrFromContext(ctx),
|
||||||
|
ctxvalue.DstAddrFromContext(ctx),
|
||||||
|
cc)
|
||||||
|
|
||||||
return cc, err
|
return cc, err
|
||||||
}
|
}
|
||||||
sniffer := &forwarder.Sniffer{
|
sniffer := &forwarder.Sniffer{
|
||||||
@@ -246,6 +248,12 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
}
|
}
|
||||||
defer cc.Close()
|
defer cc.Close()
|
||||||
|
|
||||||
|
cc = proxyproto.WrapClientConn(
|
||||||
|
h.md.proxyProtocol,
|
||||||
|
ctxvalue.SrcAddrFromContext(ctx),
|
||||||
|
ctxvalue.DstAddrFromContext(ctx),
|
||||||
|
cc)
|
||||||
|
|
||||||
log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()})
|
log = log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()})
|
||||||
ro.Src = cc.LocalAddr().String()
|
ro.Src = cc.LocalAddr().String()
|
||||||
ro.Dst = cc.RemoteAddr().String()
|
ro.Dst = cc.RemoteAddr().String()
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
type metadata struct {
|
type metadata struct {
|
||||||
readTimeout time.Duration
|
readTimeout time.Duration
|
||||||
httpKeepalive bool
|
httpKeepalive bool
|
||||||
|
proxyProtocol int
|
||||||
|
|
||||||
sniffing bool
|
sniffing bool
|
||||||
sniffingTimeout time.Duration
|
sniffingTimeout time.Duration
|
||||||
@@ -34,6 +35,7 @@ func (h *forwardHandler) parseMetadata(md mdata.Metadata) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h.md.httpKeepalive = mdutil.GetBool(md, "http.keepalive")
|
h.md.httpKeepalive = mdutil.GetBool(md, "http.keepalive")
|
||||||
|
h.md.proxyProtocol = mdutil.GetInt(md, "proxyProtocol")
|
||||||
|
|
||||||
h.md.sniffing = mdutil.GetBool(md, "sniffing")
|
h.md.sniffing = mdutil.GetBool(md, "sniffing")
|
||||||
h.md.sniffingTimeout = mdutil.GetDuration(md, "sniffing.timeout")
|
h.md.sniffingTimeout = mdutil.GetDuration(md, "sniffing.timeout")
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/core/chain"
|
"github.com/go-gost/core/chain"
|
||||||
@@ -91,15 +90,8 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
SID: string(ctxvalue.SidFromContext(ctx)),
|
SID: string(ctxvalue.SidFromContext(ctx)),
|
||||||
}
|
}
|
||||||
|
|
||||||
ro.ClientIP = conn.RemoteAddr().String()
|
if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil {
|
||||||
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
ro.ClientIP = srcAddr.String()
|
||||||
ro.ClientIP = string(clientAddr)
|
|
||||||
} else {
|
|
||||||
ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(conn.RemoteAddr().String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" {
|
|
||||||
ro.ClientIP = h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
@@ -166,6 +158,13 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address)
|
cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address)
|
||||||
ro.Route = buf.String()
|
ro.Route = buf.String()
|
||||||
|
|
||||||
|
cc = proxyproto.WrapClientConn(
|
||||||
|
h.md.proxyProtocol,
|
||||||
|
ctxvalue.SrcAddrFromContext(ctx),
|
||||||
|
ctxvalue.DstAddrFromContext(ctx),
|
||||||
|
cc)
|
||||||
|
|
||||||
return cc, err
|
return cc, err
|
||||||
}
|
}
|
||||||
sniffer := &forwarder.Sniffer{
|
sniffer := &forwarder.Sniffer{
|
||||||
@@ -260,7 +259,11 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
ro.Src = cc.LocalAddr().String()
|
ro.Src = cc.LocalAddr().String()
|
||||||
ro.Dst = cc.RemoteAddr().String()
|
ro.Dst = cc.RemoteAddr().String()
|
||||||
|
|
||||||
cc = proxyproto.WrapClientConn(h.md.proxyProtocol, conn.RemoteAddr(), convertAddr(conn.LocalAddr()), cc)
|
cc = proxyproto.WrapClientConn(
|
||||||
|
h.md.proxyProtocol,
|
||||||
|
ctxvalue.SrcAddrFromContext(ctx),
|
||||||
|
ctxvalue.DstAddrFromContext(ctx),
|
||||||
|
cc)
|
||||||
|
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
log.Infof("%s <-> %s", conn.RemoteAddr(), target.Addr)
|
log.Infof("%s <-> %s", conn.RemoteAddr(), target.Addr)
|
||||||
@@ -284,27 +287,3 @@ func (h *forwardHandler) checkRateLimit(addr net.Addr) bool {
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertAddr(addr net.Addr) net.Addr {
|
|
||||||
host, sp, _ := net.SplitHostPort(addr.String())
|
|
||||||
ip := net.ParseIP(host)
|
|
||||||
port, _ := strconv.Atoi(sp)
|
|
||||||
|
|
||||||
if ip == nil || ip.Equal(net.IPv6zero) {
|
|
||||||
ip = net.IPv4zero
|
|
||||||
}
|
|
||||||
|
|
||||||
switch addr.Network() {
|
|
||||||
case "tcp", "tcp4", "tcp6":
|
|
||||||
return &net.TCPAddr{
|
|
||||||
IP: ip,
|
|
||||||
Port: port,
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return &net.UDPAddr{
|
|
||||||
IP: ip,
|
|
||||||
Port: port,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-17
@@ -133,12 +133,8 @@ func (h *httpHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler
|
|||||||
SID: string(ctxvalue.SidFromContext(ctx)),
|
SID: string(ctxvalue.SidFromContext(ctx)),
|
||||||
}
|
}
|
||||||
|
|
||||||
ro.ClientIP = conn.RemoteAddr().String()
|
if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil {
|
||||||
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
ro.ClientIP = srcAddr.String()
|
||||||
ro.ClientIP = string(clientAddr)
|
|
||||||
}
|
|
||||||
if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" {
|
|
||||||
ro.ClientIP = h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
@@ -516,16 +512,6 @@ func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriteCloser,
|
|||||||
Header: req.Header.Clone(),
|
Header: req.Header.Clone(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if clientIP := xhttp.GetClientIP(req); clientIP != nil {
|
|
||||||
ro.ClientIP = clientIP.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
clientAddr := ro.RemoteAddr
|
|
||||||
if ro.ClientIP != "" {
|
|
||||||
if _, port, _ := net.SplitHostPort(ro.RemoteAddr); port != "" {
|
|
||||||
clientAddr = net.JoinHostPort(ro.ClientIP, port)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTP/1.0
|
// HTTP/1.0
|
||||||
http10 := req.ProtoMajor == 1 && req.ProtoMinor == 0
|
http10 := req.ProtoMajor == 1 && req.ProtoMinor == 0
|
||||||
@@ -579,7 +565,6 @@ func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriteCloser,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(clientAddr))
|
|
||||||
ctx = ctx_internal.ContextWithRecorderObject(ctx, ro)
|
ctx = ctx_internal.ContextWithRecorderObject(ctx, ro)
|
||||||
ctx = ctxvalue.ContextWithLogger(ctx, log)
|
ctx = ctxvalue.ContextWithLogger(ctx, log)
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,9 @@ func (h *http2Handler) Handle(ctx context.Context, conn net.Conn, opts ...handle
|
|||||||
Time: start,
|
Time: start,
|
||||||
SID: string(ctxvalue.SidFromContext(ctx)),
|
SID: string(ctxvalue.SidFromContext(ctx)),
|
||||||
}
|
}
|
||||||
ro.ClientIP, _, _ = net.SplitHostPort(conn.RemoteAddr().String())
|
if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil {
|
||||||
|
ro.ClientIP = srcAddr.String()
|
||||||
|
}
|
||||||
|
|
||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
"remote": conn.RemoteAddr().String(),
|
"remote": conn.RemoteAddr().String(),
|
||||||
|
|||||||
@@ -15,15 +15,7 @@ type metadata struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *http3Handler) parseMetadata(md mdata.Metadata) error {
|
func (h *http3Handler) parseMetadata(md mdata.Metadata) error {
|
||||||
const (
|
if m := mdutil.GetStringMapString(md, "header"); len(m) > 0 {
|
||||||
header = "header"
|
|
||||||
probeResistKey = "probeResistance"
|
|
||||||
probeResistKeyX = "probe_resist"
|
|
||||||
knock = "knock"
|
|
||||||
hash = "hash"
|
|
||||||
)
|
|
||||||
|
|
||||||
if m := mdutil.GetStringMapString(md, header); len(m) > 0 {
|
|
||||||
hd := http.Header{}
|
hd := http.Header{}
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
hd.Add(k, v)
|
hd.Add(k, v)
|
||||||
@@ -31,20 +23,17 @@ func (h *http3Handler) parseMetadata(md mdata.Metadata) error {
|
|||||||
h.md.header = hd
|
h.md.header = hd
|
||||||
}
|
}
|
||||||
|
|
||||||
pr := mdutil.GetString(md, probeResistKey)
|
pr := mdutil.GetString(md, "probeResistance", "probe_resist")
|
||||||
if pr == "" {
|
|
||||||
pr = mdutil.GetString(md, probeResistKeyX)
|
|
||||||
}
|
|
||||||
if pr != "" {
|
if pr != "" {
|
||||||
if ss := strings.SplitN(pr, ":", 2); len(ss) == 2 {
|
if ss := strings.SplitN(pr, ":", 2); len(ss) == 2 {
|
||||||
h.md.probeResistance = &probeResistance{
|
h.md.probeResistance = &probeResistance{
|
||||||
Type: ss[0],
|
Type: ss[0],
|
||||||
Value: ss[1],
|
Value: ss[1],
|
||||||
Knock: mdutil.GetString(md, knock),
|
Knock: mdutil.GetString(md, "knock"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.md.hash = mdutil.GetString(md, hash)
|
h.md.hash = mdutil.GetString(md, "hash")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,13 +81,17 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
|
|||||||
Time: start,
|
Time: start,
|
||||||
SID: string(ctxvalue.SidFromContext(ctx)),
|
SID: string(ctxvalue.SidFromContext(ctx)),
|
||||||
}
|
}
|
||||||
ro.ClientIP, _, _ = net.SplitHostPort(conn.RemoteAddr().String())
|
|
||||||
|
if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil {
|
||||||
|
ro.ClientIP = srcAddr.String()
|
||||||
|
}
|
||||||
|
|
||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
|
"network": ro.Network,
|
||||||
"remote": conn.RemoteAddr().String(),
|
"remote": conn.RemoteAddr().String(),
|
||||||
"local": conn.LocalAddr().String(),
|
"local": conn.LocalAddr().String(),
|
||||||
"sid": ctxvalue.SidFromContext(ctx),
|
"sid": ctxvalue.SidFromContext(ctx),
|
||||||
"network": ro.Network,
|
"client": ro.ClientIP,
|
||||||
})
|
})
|
||||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||||
|
|
||||||
|
|||||||
@@ -112,12 +112,8 @@ func (h *relayHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle
|
|||||||
SID: string(ctxvalue.SidFromContext(ctx)),
|
SID: string(ctxvalue.SidFromContext(ctx)),
|
||||||
}
|
}
|
||||||
|
|
||||||
ro.ClientIP = conn.RemoteAddr().String()
|
if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil {
|
||||||
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
ro.ClientIP = srcAddr.String()
|
||||||
ro.ClientIP = string(clientAddr)
|
|
||||||
}
|
|
||||||
if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" {
|
|
||||||
ro.ClientIP = h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
|
|||||||
@@ -81,12 +81,8 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
|
|||||||
SID: string(ctxvalue.SidFromContext(ctx)),
|
SID: string(ctxvalue.SidFromContext(ctx)),
|
||||||
}
|
}
|
||||||
|
|
||||||
ro.ClientIP = conn.RemoteAddr().String()
|
if srcAddr := ctxvalue.SrcAddrFromContext(ctx); srcAddr != nil {
|
||||||
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
ro.ClientIP = srcAddr.String()
|
||||||
ro.ClientIP = string(clientAddr)
|
|
||||||
}
|
|
||||||
if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" {
|
|
||||||
ro.ClientIP = h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
@@ -131,6 +127,7 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
|
|||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address)
|
cc, err := h.options.Router.Dial(ctxvalue.ContextWithBuffer(ctx, &buf), "tcp", address)
|
||||||
ro.Route = buf.String()
|
ro.Route = buf.String()
|
||||||
|
|
||||||
return cc, err
|
return cc, err
|
||||||
}
|
}
|
||||||
dialTLS := func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error) {
|
dialTLS := func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error) {
|
||||||
|
|||||||
+6
-2
@@ -26,8 +26,12 @@ type RemoteAddr interface {
|
|||||||
RemoteAddr() net.Addr
|
RemoteAddr() net.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClientAddr interface {
|
type SrcAddr interface {
|
||||||
ClientAddr() net.Addr
|
SrcAddr() net.Addr
|
||||||
|
}
|
||||||
|
|
||||||
|
type DstAddr interface {
|
||||||
|
DstAddr() net.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// tcpraw.TCPConn
|
// tcpraw.TCPConn
|
||||||
|
|||||||
@@ -69,13 +69,13 @@ func pipeBuffer(dst io.ReadWriteCloser, src io.ReadWriteCloser, bufferSize int)
|
|||||||
if cw, ok := dst.(xio.CloseWrite); ok {
|
if cw, ok := dst.(xio.CloseWrite); ok {
|
||||||
if e := cw.CloseWrite(); e == xio.ErrUnsupported {
|
if e := cw.CloseWrite(); e == xio.ErrUnsupported {
|
||||||
dst.Close()
|
dst.Close()
|
||||||
|
} else {
|
||||||
|
// Set TCP half-close timeout.
|
||||||
|
xio.SetReadDeadline(dst, time.Now().Add(tcpWaitTimeout))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dst.Close()
|
dst.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set TCP half-close timeout.
|
|
||||||
xio.SetReadDeadline(dst, time.Now().Add(tcpWaitTimeout))
|
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package proxyproto
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
xio "github.com/go-gost/x/internal/io"
|
xio "github.com/go-gost/x/internal/io"
|
||||||
proxyproto "github.com/pires/go-proxyproto"
|
proxyproto "github.com/pires/go-proxyproto"
|
||||||
@@ -11,6 +12,28 @@ type serverConn struct {
|
|||||||
net.Conn
|
net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *serverConn) RemoteAddr() net.Addr {
|
||||||
|
if conn, ok := c.Conn.(*proxyproto.Conn); ok {
|
||||||
|
return conn.Raw().RemoteAddr()
|
||||||
|
}
|
||||||
|
return c.Conn.RemoteAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *serverConn) LocalAddr() net.Addr {
|
||||||
|
if conn, ok := c.Conn.(*proxyproto.Conn); ok {
|
||||||
|
return conn.Raw().LocalAddr()
|
||||||
|
}
|
||||||
|
return c.Conn.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *serverConn) SrcAddr() net.Addr {
|
||||||
|
return c.Conn.RemoteAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *serverConn) DstAddr() net.Addr {
|
||||||
|
return c.Conn.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
func (c *serverConn) CloseRead() error {
|
func (c *serverConn) CloseRead() error {
|
||||||
if sc, ok := c.Conn.(xio.CloseRead); ok {
|
if sc, ok := c.Conn.(xio.CloseRead); ok {
|
||||||
return sc.CloseRead()
|
return sc.CloseRead()
|
||||||
@@ -36,7 +59,14 @@ func (c *serverConn) CloseWrite() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func WrapClientConn(ppv int, src, dst net.Addr, c net.Conn) net.Conn {
|
func WrapClientConn(ppv int, src, dst net.Addr, c net.Conn) net.Conn {
|
||||||
if ppv <= 0 {
|
if ppv <= 0 || c == nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
if src = convertAddr(src); src == nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
if dst = convertAddr(dst); dst == nil {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,3 +74,31 @@ func WrapClientConn(ppv int, src, dst net.Addr, c net.Conn) net.Conn {
|
|||||||
header.WriteTo(c)
|
header.WriteTo(c)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convertAddr(addr net.Addr) net.Addr {
|
||||||
|
if addr == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
host, sp, _ := net.SplitHostPort(addr.String())
|
||||||
|
ip := net.ParseIP(host)
|
||||||
|
port, _ := strconv.Atoi(sp)
|
||||||
|
|
||||||
|
if ip == nil || ip.Equal(net.IPv6zero) {
|
||||||
|
ip = net.IPv4zero
|
||||||
|
}
|
||||||
|
|
||||||
|
switch addr.Network() {
|
||||||
|
case "tcp", "tcp4", "tcp6":
|
||||||
|
return &net.TCPAddr{
|
||||||
|
IP: ip,
|
||||||
|
Port: port,
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return &net.UDPAddr{
|
||||||
|
IP: ip,
|
||||||
|
Port: port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+26
-9
@@ -5,6 +5,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
xio "github.com/go-gost/x/internal/io"
|
||||||
xnet "github.com/go-gost/x/internal/net"
|
xnet "github.com/go-gost/x/internal/net"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
@@ -13,14 +14,16 @@ type WebsocketConn interface {
|
|||||||
net.Conn
|
net.Conn
|
||||||
WriteMessage(int, []byte) error
|
WriteMessage(int, []byte) error
|
||||||
ReadMessage() (int, []byte, error)
|
ReadMessage() (int, []byte, error)
|
||||||
xnet.ClientAddr
|
xnet.SrcAddr
|
||||||
|
xio.CloseRead
|
||||||
|
xio.CloseWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
type websocketConn struct {
|
type websocketConn struct {
|
||||||
*websocket.Conn
|
*websocket.Conn
|
||||||
rb []byte
|
rb []byte
|
||||||
clientAddr net.Addr
|
srcAddr net.Addr
|
||||||
mux sync.Mutex
|
mux sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func Conn(conn *websocket.Conn) WebsocketConn {
|
func Conn(conn *websocket.Conn) WebsocketConn {
|
||||||
@@ -29,10 +32,10 @@ func Conn(conn *websocket.Conn) WebsocketConn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConnWithClientAddr(conn *websocket.Conn, clientAddr net.Addr) WebsocketConn {
|
func ConnWithSrcAddr(conn *websocket.Conn, srcAddr net.Addr) WebsocketConn {
|
||||||
return &websocketConn{
|
return &websocketConn{
|
||||||
Conn: conn,
|
Conn: conn,
|
||||||
clientAddr: clientAddr,
|
srcAddr: srcAddr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,6 +80,20 @@ func (c *websocketConn) SetWriteDeadline(t time.Time) error {
|
|||||||
return c.Conn.SetWriteDeadline(t)
|
return c.Conn.SetWriteDeadline(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *websocketConn) ClientAddr() net.Addr {
|
func (c *websocketConn) SrcAddr() net.Addr {
|
||||||
return c.clientAddr
|
return c.srcAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *websocketConn) CloseRead() error {
|
||||||
|
if sc, ok := c.Conn.NetConn().(xio.CloseRead); ok {
|
||||||
|
return sc.CloseRead()
|
||||||
|
}
|
||||||
|
return xio.ErrUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *websocketConn) CloseWrite() error {
|
||||||
|
if sc, ok := c.Conn.NetConn().(xio.CloseWrite); ok {
|
||||||
|
return sc.CloseWrite()
|
||||||
|
}
|
||||||
|
return xio.ErrUnsupported
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type conn struct {
|
type conn struct {
|
||||||
session *wt.Session
|
session *wt.Session
|
||||||
stream *wt.Stream
|
stream *wt.Stream
|
||||||
clientAddr net.Addr
|
srcAddr net.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func Conn(session *wt.Session, stream *wt.Stream) net.Conn {
|
func Conn(session *wt.Session, stream *wt.Stream) net.Conn {
|
||||||
@@ -20,11 +20,11 @@ func Conn(session *wt.Session, stream *wt.Stream) net.Conn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConnWithClientAddr(session *wt.Session, stream *wt.Stream, clientAddr net.Addr) net.Conn {
|
func ConnWithSrcAddr(session *wt.Session, stream *wt.Stream, srcAddr net.Addr) net.Conn {
|
||||||
return &conn{
|
return &conn{
|
||||||
session: session,
|
session: session,
|
||||||
stream: stream,
|
stream: stream,
|
||||||
clientAddr: clientAddr,
|
srcAddr: srcAddr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,8 +48,8 @@ func (c *conn) RemoteAddr() net.Addr {
|
|||||||
return c.session.RemoteAddr()
|
return c.session.RemoteAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) ClientAddr() net.Addr {
|
func (c *conn) SrcAddr() net.Addr {
|
||||||
return c.clientAddr
|
return c.srcAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) SetDeadline(t time.Time) error {
|
func (c *conn) SetDeadline(t time.Time) error {
|
||||||
|
|||||||
@@ -107,9 +107,16 @@ func (c *limitConn) Metadata() metadata.Metadata {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *limitConn) ClientAddr() net.Addr {
|
func (c *limitConn) SrcAddr() net.Addr {
|
||||||
if sc, ok := c.Conn.(xnet.ClientAddr); ok {
|
if sc, ok := c.Conn.(xnet.SrcAddr); ok {
|
||||||
return sc.ClientAddr()
|
return sc.SrcAddr()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *limitConn) DstAddr() net.Addr {
|
||||||
|
if sc, ok := c.Conn.(xnet.DstAddr); ok {
|
||||||
|
return sc.DstAddr()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-10
@@ -3,7 +3,6 @@ package http2
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
mdata "github.com/go-gost/core/metadata"
|
mdata "github.com/go-gost/core/metadata"
|
||||||
@@ -11,13 +10,11 @@ import (
|
|||||||
|
|
||||||
// a dummy HTTP2 server conn used by HTTP2 handler
|
// a dummy HTTP2 server conn used by HTTP2 handler
|
||||||
type conn struct {
|
type conn struct {
|
||||||
md mdata.Metadata
|
md mdata.Metadata
|
||||||
r *http.Request
|
laddr net.Addr
|
||||||
w http.ResponseWriter
|
raddr net.Addr
|
||||||
laddr net.Addr
|
srcAddr net.Addr
|
||||||
raddr net.Addr
|
closed chan struct{}
|
||||||
clientAddr net.Addr
|
|
||||||
closed chan struct{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Read(b []byte) (n int, err error) {
|
func (c *conn) Read(b []byte) (n int, err error) {
|
||||||
@@ -45,8 +42,8 @@ func (c *conn) RemoteAddr() net.Addr {
|
|||||||
return c.raddr
|
return c.raddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) ClientAddr() net.Addr {
|
func (c *conn) SrcAddr() net.Addr {
|
||||||
return c.clientAddr
|
return c.srcAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) SetDeadline(t time.Time) error {
|
func (c *conn) SetDeadline(t time.Time) error {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type conn struct {
|
|||||||
w io.Writer
|
w io.Writer
|
||||||
remoteAddr net.Addr
|
remoteAddr net.Addr
|
||||||
localAddr net.Addr
|
localAddr net.Addr
|
||||||
clientAddr net.Addr
|
srcAddr net.Addr
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,8 +50,8 @@ func (c *conn) RemoteAddr() net.Addr {
|
|||||||
return c.remoteAddr
|
return c.remoteAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) ClientAddr() net.Addr {
|
func (c *conn) SrcAddr() net.Addr {
|
||||||
return c.clientAddr
|
return c.srcAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) SetDeadline(t time.Time) error {
|
func (c *conn) SetDeadline(t time.Time) error {
|
||||||
|
|||||||
@@ -157,7 +157,17 @@ func (l *h2Listener) Close() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *h2Listener) handleFunc(w http.ResponseWriter, r *http.Request) {
|
func (l *h2Listener) handleFunc(w http.ResponseWriter, r *http.Request) {
|
||||||
if l.logger.IsLevelEnabled(logger.TraceLevel) {
|
clientIP := xhttp.GetClientIP(r)
|
||||||
|
cip := ""
|
||||||
|
if clientIP != nil {
|
||||||
|
cip = clientIP.String()
|
||||||
|
}
|
||||||
|
log := l.logger.WithFields(map[string]any{
|
||||||
|
"local": l.addr.String(),
|
||||||
|
"remote": r.RemoteAddr,
|
||||||
|
"client": cip,
|
||||||
|
})
|
||||||
|
if log.IsLevelEnabled(logger.TraceLevel) {
|
||||||
dump, _ := httputil.DumpRequest(r, false)
|
dump, _ := httputil.DumpRequest(r, false)
|
||||||
l.logger.Trace(string(dump))
|
l.logger.Trace(string(dump))
|
||||||
}
|
}
|
||||||
@@ -195,14 +205,13 @@ func (l *h2Listener) upgrade(w http.ResponseWriter, r *http.Request) (*conn, err
|
|||||||
remoteAddr, _ := net.ResolveTCPAddr("tcp", r.RemoteAddr)
|
remoteAddr, _ := net.ResolveTCPAddr("tcp", r.RemoteAddr)
|
||||||
if remoteAddr == nil {
|
if remoteAddr == nil {
|
||||||
remoteAddr = &net.TCPAddr{
|
remoteAddr = &net.TCPAddr{
|
||||||
IP: net.IPv4zero,
|
IP: net.IPv4zero,
|
||||||
Port: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var clientAddr net.Addr
|
var srcAddr net.Addr
|
||||||
if clientIP := xhttp.GetClientIP(r); clientIP != nil {
|
if clientIP := xhttp.GetClientIP(r); clientIP != nil {
|
||||||
clientAddr = &net.IPAddr{IP: clientIP}
|
srcAddr = &net.TCPAddr{IP: clientIP}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &conn{
|
return &conn{
|
||||||
@@ -210,7 +219,7 @@ func (l *h2Listener) upgrade(w http.ResponseWriter, r *http.Request) (*conn, err
|
|||||||
w: flushWriter{w},
|
w: flushWriter{w},
|
||||||
localAddr: l.addr,
|
localAddr: l.addr,
|
||||||
remoteAddr: remoteAddr,
|
remoteAddr: remoteAddr,
|
||||||
clientAddr: clientAddr,
|
srcAddr: srcAddr,
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,21 +139,29 @@ func (l *http2Listener) Close() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *http2Listener) handleFunc(w http.ResponseWriter, r *http.Request) {
|
func (l *http2Listener) handleFunc(w http.ResponseWriter, r *http.Request) {
|
||||||
raddr, _ := net.ResolveTCPAddr("tcp", r.RemoteAddr)
|
remoteAddr, _ := net.ResolveTCPAddr("tcp", r.RemoteAddr)
|
||||||
|
if remoteAddr == nil {
|
||||||
|
remoteAddr = &net.TCPAddr{
|
||||||
|
IP: net.IPv4zero,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var srcAddr net.Addr
|
||||||
|
if clientIP := xhttp.GetClientIP(r); clientIP != nil {
|
||||||
|
srcAddr = &net.TCPAddr{IP: clientIP}
|
||||||
|
}
|
||||||
|
|
||||||
conn := &conn{
|
conn := &conn{
|
||||||
laddr: l.addr,
|
laddr: l.addr,
|
||||||
raddr: raddr,
|
raddr: remoteAddr,
|
||||||
closed: make(chan struct{}),
|
srcAddr: srcAddr,
|
||||||
|
closed: make(chan struct{}),
|
||||||
md: mdx.NewMetadata(map[string]any{
|
md: mdx.NewMetadata(map[string]any{
|
||||||
"r": r,
|
"r": r,
|
||||||
"w": w,
|
"w": w,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
if clientIP := xhttp.GetClientIP(r); clientIP != nil {
|
|
||||||
conn.clientAddr = &net.IPAddr{IP: clientIP}
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case l.cqueue <- conn:
|
case l.cqueue <- conn:
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import (
|
|||||||
|
|
||||||
// a dummy HTTP3 server conn used by HTTP3 handler
|
// a dummy HTTP3 server conn used by HTTP3 handler
|
||||||
type conn struct {
|
type conn struct {
|
||||||
md mdata.Metadata
|
md mdata.Metadata
|
||||||
laddr net.Addr
|
laddr net.Addr
|
||||||
raddr net.Addr
|
raddr net.Addr
|
||||||
clientAddr net.Addr
|
srcAddr net.Addr
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Read(b []byte) (n int, err error) {
|
func (c *conn) Read(b []byte) (n int, err error) {
|
||||||
@@ -42,8 +42,8 @@ func (c *conn) RemoteAddr() net.Addr {
|
|||||||
return c.raddr
|
return c.raddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) ClientAddr() net.Addr {
|
func (c *conn) SrcAddr() net.Addr {
|
||||||
return c.clientAddr
|
return c.srcAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) SetDeadline(t time.Time) error {
|
func (c *conn) SetDeadline(t time.Time) error {
|
||||||
|
|||||||
@@ -125,10 +125,15 @@ func (l *http3Listener) Close() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *http3Listener) handleFunc(w http.ResponseWriter, r *http.Request) {
|
func (l *http3Listener) handleFunc(w http.ResponseWriter, r *http.Request) {
|
||||||
raddr, _ := net.ResolveTCPAddr("tcp", r.RemoteAddr)
|
remoteAddr, _ := net.ResolveTCPAddr("tcp", r.RemoteAddr)
|
||||||
|
if remoteAddr == nil {
|
||||||
|
remoteAddr = &net.TCPAddr{
|
||||||
|
IP: net.IPv4zero,
|
||||||
|
}
|
||||||
|
}
|
||||||
conn := &conn{
|
conn := &conn{
|
||||||
laddr: l.addr,
|
laddr: l.addr,
|
||||||
raddr: raddr,
|
raddr: remoteAddr,
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
md: mdx.NewMetadata(map[string]any{
|
md: mdx.NewMetadata(map[string]any{
|
||||||
"r": r,
|
"r": r,
|
||||||
@@ -137,7 +142,7 @@ func (l *http3Listener) handleFunc(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if clientIP := xhttp.GetClientIP(r); clientIP != nil {
|
if clientIP := xhttp.GetClientIP(r); clientIP != nil {
|
||||||
conn.clientAddr = &net.IPAddr{IP: clientIP}
|
conn.srcAddr = &net.UDPAddr{IP: clientIP}
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
|||||||
@@ -176,15 +176,15 @@ func (l *wtListener) upgrade(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var clientAddr net.Addr
|
var srcAddr net.Addr
|
||||||
if clientIP != nil {
|
if clientIP != nil {
|
||||||
clientAddr = &net.IPAddr{IP: clientIP}
|
srcAddr = &net.UDPAddr{IP: clientIP}
|
||||||
}
|
}
|
||||||
|
|
||||||
l.mux(s, clientAddr, log)
|
l.mux(s, srcAddr, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *wtListener) mux(s *wt.Session, clientAddr net.Addr, log logger.Logger) (err error) {
|
func (l *wtListener) mux(s *wt.Session, srcAddr net.Addr, log logger.Logger) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.CloseWithError(1, err.Error())
|
s.CloseWithError(1, err.Error())
|
||||||
@@ -202,7 +202,7 @@ func (l *wtListener) mux(s *wt.Session, clientAddr net.Addr, log logger.Logger)
|
|||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case l.cqueue <- wt_util.ConnWithClientAddr(s, stream, clientAddr):
|
case l.cqueue <- wt_util.ConnWithSrcAddr(s, stream, srcAddr):
|
||||||
default:
|
default:
|
||||||
stream.Close()
|
stream.Close()
|
||||||
l.logger.Warnf("connection queue is full, stream %v discarded", stream.StreamID())
|
l.logger.Warnf("connection queue is full, stream %v discarded", stream.StreamID())
|
||||||
|
|||||||
@@ -184,15 +184,15 @@ func (l *mwsListener) upgrade(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var clientAddr net.Addr
|
var srcAddr net.Addr
|
||||||
if clientIP != nil {
|
if clientIP != nil {
|
||||||
clientAddr = &net.IPAddr{IP: clientIP}
|
srcAddr = &net.TCPAddr{IP: clientIP}
|
||||||
}
|
}
|
||||||
|
|
||||||
l.mux(ws_util.Conn(conn), clientAddr, log)
|
l.mux(ws_util.Conn(conn), srcAddr, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *mwsListener) mux(conn net.Conn, clientAddr net.Addr, log logger.Logger) {
|
func (l *mwsListener) mux(conn net.Conn, srcAddr net.Addr, log logger.Logger) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
session, err := mux.ServerSession(conn, l.md.muxCfg)
|
session, err := mux.ServerSession(conn, l.md.muxCfg)
|
||||||
@@ -210,7 +210,7 @@ func (l *mwsListener) mux(conn net.Conn, clientAddr net.Addr, log logger.Logger)
|
|||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case l.cqueue <- &connWithClientAddr{Conn: stream, clientAddr: clientAddr}:
|
case l.cqueue <- &connWithSrcAddr{Conn: stream, srcAddr: srcAddr}:
|
||||||
default:
|
default:
|
||||||
stream.Close()
|
stream.Close()
|
||||||
log.Warnf("connection queue is full, client %s discarded", stream.RemoteAddr())
|
log.Warnf("connection queue is full, client %s discarded", stream.RemoteAddr())
|
||||||
@@ -218,11 +218,11 @@ func (l *mwsListener) mux(conn net.Conn, clientAddr net.Addr, log logger.Logger)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type connWithClientAddr struct {
|
type connWithSrcAddr struct {
|
||||||
net.Conn
|
net.Conn
|
||||||
clientAddr net.Addr
|
srcAddr net.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *connWithClientAddr) ClientAddr() net.Addr {
|
func (c *connWithSrcAddr) SrcAddr() net.Addr {
|
||||||
return c.clientAddr
|
return c.srcAddr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,13 +179,13 @@ func (l *wsListener) upgrade(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var clientAddr net.Addr
|
var srcAddr net.Addr
|
||||||
if clientIP != nil {
|
if clientIP != nil {
|
||||||
clientAddr = &net.IPAddr{IP: clientIP}
|
srcAddr = &net.TCPAddr{IP: clientIP}
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case l.cqueue <- ws_util.ConnWithClientAddr(conn, clientAddr):
|
case l.cqueue <- ws_util.ConnWithSrcAddr(conn, srcAddr):
|
||||||
default:
|
default:
|
||||||
conn.Close()
|
conn.Close()
|
||||||
log.Warnf("connection queue is full, client %s discarded", conn.RemoteAddr())
|
log.Warnf("connection queue is full, client %s discarded", conn.RemoteAddr())
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
type mapMetadata map[string]any
|
type mapMetadata map[string]any
|
||||||
|
|
||||||
func NewMetadata(m map[string]any) metadata.Metadata {
|
func NewMetadata(m map[string]any) metadata.Metadata {
|
||||||
if len(m) == 0 {
|
if m == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
md := make(map[string]any)
|
md := make(map[string]any)
|
||||||
|
|||||||
+10
-3
@@ -81,9 +81,16 @@ func (c *serverConn) Metadata() metadata.Metadata {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *serverConn) ClientAddr() net.Addr {
|
func (c *serverConn) SrcAddr() net.Addr {
|
||||||
if sc, ok := c.Conn.(xnet.ClientAddr); ok {
|
if sc, ok := c.Conn.(xnet.SrcAddr); ok {
|
||||||
return sc.ClientAddr()
|
return sc.SrcAddr()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *serverConn) DstAddr() net.Addr {
|
||||||
|
if sc, ok := c.Conn.(xnet.DstAddr); ok {
|
||||||
|
return sc.DstAddr()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,9 +83,16 @@ func (c *conn) Metadata() metadata.Metadata {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) ClientAddr() net.Addr {
|
func (c *conn) SrcAddr() net.Addr {
|
||||||
if sc, ok := c.Conn.(xnet.ClientAddr); ok {
|
if sc, ok := c.Conn.(xnet.SrcAddr); ok {
|
||||||
return sc.ClientAddr()
|
return sc.SrcAddr()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *conn) DstAddr() net.Addr {
|
||||||
|
if sc, ok := c.Conn.(xnet.DstAddr); ok {
|
||||||
|
return sc.DstAddr()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-15
@@ -206,26 +206,38 @@ func (s *defaultService) Serve() error {
|
|||||||
s.setState(StateReady)
|
s.setState(StateReady)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAddr := conn.RemoteAddr().String()
|
|
||||||
if ca, ok := conn.(xnet.ClientAddr); ok {
|
|
||||||
if addr := ca.ClientAddr(); addr != nil {
|
|
||||||
clientAddr = addr.String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clientIP := clientAddr
|
|
||||||
if h, _, _ := net.SplitHostPort(clientAddr); h != "" {
|
|
||||||
clientIP = h
|
|
||||||
}
|
|
||||||
|
|
||||||
sid := xid.New().String()
|
sid := xid.New().String()
|
||||||
ctx := ctxvalue.ContextWithSid(ctx, ctxvalue.Sid(sid))
|
ctx := ctxvalue.ContextWithSid(ctx, ctxvalue.Sid(sid))
|
||||||
ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(clientAddr))
|
|
||||||
ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: clientIP})
|
|
||||||
|
|
||||||
log := s.options.logger.WithFields(map[string]any{
|
log := s.options.logger.WithFields(map[string]any{
|
||||||
"sid": sid,
|
"sid": sid,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
srcAddr := conn.RemoteAddr()
|
||||||
|
if a, ok := conn.(xnet.SrcAddr); ok {
|
||||||
|
if addr := a.SrcAddr(); addr != nil {
|
||||||
|
srcAddr = addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx = ctxvalue.ContextWithSrcAddr(ctx, srcAddr)
|
||||||
|
|
||||||
|
clientAddr := srcAddr.String()
|
||||||
|
ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(clientAddr))
|
||||||
|
|
||||||
|
dstAddr := conn.LocalAddr()
|
||||||
|
if a, ok := conn.(xnet.DstAddr); ok {
|
||||||
|
if addr := a.DstAddr(); addr != nil {
|
||||||
|
dstAddr = addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx = ctxvalue.ContextWithDstAddr(ctx, dstAddr)
|
||||||
|
|
||||||
|
clientIP := clientAddr
|
||||||
|
if h, _, _ := net.SplitHostPort(clientIP); h != "" {
|
||||||
|
clientIP = h
|
||||||
|
}
|
||||||
|
ctx = ctxvalue.ContextWithHash(ctx, &ctxvalue.Hash{Source: clientIP})
|
||||||
|
|
||||||
for _, rec := range s.options.recorders {
|
for _, rec := range s.options.recorders {
|
||||||
if rec.Record == recorder.RecorderServiceClientAddress {
|
if rec.Record == recorder.RecorderServiceClientAddress {
|
||||||
if err := rec.Recorder.Record(ctx, []byte(clientIP)); err != nil {
|
if err := rec.Recorder.Record(ctx, []byte(clientIP)); err != nil {
|
||||||
@@ -235,9 +247,9 @@ func (s *defaultService) Serve() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.options.admission != nil &&
|
if s.options.admission != nil &&
|
||||||
!s.options.admission.Admit(ctx, clientAddr) {
|
!s.options.admission.Admit(ctx, srcAddr.String()) {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
log.Debugf("admission: %s is denied", clientAddr)
|
log.Debugf("admission: %s is denied", srcAddr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user