Merge branch 'refs/heads/master' into dev

This commit is contained in:
wenyifan 2024-07-05 13:45:23 +08:00
commit 3c1985e980
68 changed files with 385 additions and 221 deletions

View File

@ -7,10 +7,10 @@ import (
"os" "os"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/x/config" "github.com/go-gost/x/config"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
"github.com/go-gost/x/service" "github.com/go-gost/x/service"
"github.com/go-gost/x/stats"
) )
type serviceStatus interface { type serviceStatus interface {

View File

@ -487,6 +487,7 @@ type HopConfig struct {
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"` Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"` HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"` Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
Metadata map[string]any `yaml:",omitempty" json:"metadata,omitempty"`
} }
type NodeConfig struct { type NodeConfig struct {
@ -500,6 +501,7 @@ type NodeConfig struct {
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"` Interface string `yaml:",omitempty" json:"interface,omitempty"`
Netns string `yaml:",omitempty" json:"netns,omitempty"`
SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,omitempty"` SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,omitempty"`
Filter *NodeFilterConfig `yaml:",omitempty" json:"filter,omitempty"` Filter *NodeFilterConfig `yaml:",omitempty" json:"filter,omitempty"`
HTTP *HTTPNodeConfig `yaml:",omitempty" json:"http,omitempty"` HTTP *HTTPNodeConfig `yaml:",omitempty" json:"http,omitempty"`

View File

@ -8,7 +8,9 @@ import (
"github.com/go-gost/core/chain" "github.com/go-gost/core/chain"
"github.com/go-gost/core/hop" "github.com/go-gost/core/hop"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
mdutil "github.com/go-gost/core/metadata/util"
"github.com/go-gost/x/config" "github.com/go-gost/x/config"
"github.com/go-gost/x/config/parsing"
bypass_parser "github.com/go-gost/x/config/parsing/bypass" bypass_parser "github.com/go-gost/x/config/parsing/bypass"
node_parser "github.com/go-gost/x/config/parsing/node" node_parser "github.com/go-gost/x/config/parsing/node"
selector_parser "github.com/go-gost/x/config/parsing/selector" selector_parser "github.com/go-gost/x/config/parsing/selector"
@ -16,6 +18,7 @@ import (
hop_plugin "github.com/go-gost/x/hop/plugin" hop_plugin "github.com/go-gost/x/hop/plugin"
"github.com/go-gost/x/internal/loader" "github.com/go-gost/x/internal/loader"
"github.com/go-gost/x/internal/plugin" "github.com/go-gost/x/internal/plugin"
"github.com/go-gost/x/metadata"
) )
func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) { func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) {
@ -47,6 +50,16 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) {
} }
} }
ifce := cfg.Interface
var netns string
if cfg.Metadata != nil {
md := metadata.NewMetadata(cfg.Metadata)
if v := mdutil.GetString(md, parsing.MDKeyInterface); v != "" {
ifce = v
}
netns = mdutil.GetString(md, "netns")
}
var nodes []*chain.Node var nodes []*chain.Node
for _, v := range cfg.Nodes { for _, v := range cfg.Nodes {
if v == nil { if v == nil {
@ -60,8 +73,12 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) {
v.Hosts = cfg.Hosts v.Hosts = cfg.Hosts
} }
if v.Interface == "" { if v.Interface == "" {
v.Interface = cfg.Interface v.Interface = ifce
} }
if v.Netns == "" {
v.Netns = netns
}
if v.SockOpts == nil { if v.SockOpts == nil {
v.SockOpts = cfg.SockOpts v.SockOpts = cfg.SockOpts
} }

View File

@ -5,7 +5,6 @@ import (
"net" "net"
"regexp" "regexp"
"strings" "strings"
"time"
"github.com/go-gost/core/bypass" "github.com/go-gost/core/bypass"
"github.com/go-gost/core/chain" "github.com/go-gost/core/chain"
@ -143,8 +142,8 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
tr := chain.NewTransport(d, cr, tr := chain.NewTransport(d, cr,
chain.AddrTransportOption(cfg.Addr), chain.AddrTransportOption(cfg.Addr),
chain.InterfaceTransportOption(cfg.Interface), chain.InterfaceTransportOption(cfg.Interface),
chain.NetnsTransportOption(cfg.Netns),
chain.SockOptsTransportOption(sockOpts), chain.SockOptsTransportOption(sockOpts),
chain.TimeoutTransportOption(10*time.Second),
) )
opts := []chain.NodeOption{ opts := []chain.NodeOption{

View File

@ -2,6 +2,7 @@ package service
import ( import (
"fmt" "fmt"
"runtime"
"strings" "strings"
"time" "time"
@ -14,6 +15,7 @@ import (
"github.com/go-gost/core/listener" "github.com/go-gost/core/listener"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
mdutil "github.com/go-gost/core/metadata/util" mdutil "github.com/go-gost/core/metadata/util"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/core/recorder" "github.com/go-gost/core/recorder"
"github.com/go-gost/core/selector" "github.com/go-gost/core/selector"
"github.com/go-gost/core/service" "github.com/go-gost/core/service"
@ -31,7 +33,7 @@ import (
"github.com/go-gost/x/metadata" "github.com/go-gost/x/metadata"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
xservice "github.com/go-gost/x/service" xservice "github.com/go-gost/x/service"
"github.com/go-gost/x/stats" "github.com/vishvananda/netns"
) )
func ParseService(cfg *config.ServiceConfig) (service.Service, error) { func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
@ -61,17 +63,13 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
"handler": cfg.Handler.Type, "handler": cfg.Handler.Type,
}) })
listenerLogger := serviceLogger.WithFields(map[string]any{
"kind": "listener",
})
tlsCfg := cfg.Listener.TLS tlsCfg := cfg.Listener.TLS
if tlsCfg == nil { if tlsCfg == nil {
tlsCfg = &config.TLSConfig{} tlsCfg = &config.TLSConfig{}
} }
tlsConfig, err := tls_util.LoadServerConfig(tlsCfg) tlsConfig, err := tls_util.LoadServerConfig(tlsCfg)
if err != nil { if err != nil {
listenerLogger.Error(err) serviceLogger.Error(err)
return nil, err return nil, err
} }
if tlsConfig == nil { if tlsConfig == nil {
@ -104,6 +102,8 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
var ignoreChain bool var ignoreChain bool
var pStats *stats.Stats var pStats *stats.Stats
var observePeriod time.Duration var observePeriod time.Duration
var netnsIn, netnsOut string
var dialTimeout time.Duration
if cfg.Metadata != nil { if cfg.Metadata != nil {
md := metadata.NewMetadata(cfg.Metadata) md := metadata.NewMetadata(cfg.Metadata)
ppv = mdutil.GetInt(md, parsing.MDKeyProxyProtocol) ppv = mdutil.GetInt(md, parsing.MDKeyProxyProtocol)
@ -125,25 +125,65 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
pStats = &stats.Stats{} pStats = &stats.Stats{}
} }
observePeriod = mdutil.GetDuration(md, "observePeriod") observePeriod = mdutil.GetDuration(md, "observePeriod")
netnsIn = mdutil.GetString(md, "netns")
netnsOut = mdutil.GetString(md, "netns.out")
dialTimeout = mdutil.GetDuration(md, "dialTimeout")
}
listenerLogger := serviceLogger.WithFields(map[string]any{
"kind": "listener",
})
routerOpts := []chain.RouterOption{
chain.TimeoutRouterOption(dialTimeout),
chain.InterfaceRouterOption(ifce),
chain.NetnsRouterOption(netnsOut),
chain.SockOptsRouterOption(sockOpts),
chain.ResolverRouterOption(registry.ResolverRegistry().Get(cfg.Resolver)),
chain.HostMapperRouterOption(registry.HostsRegistry().Get(cfg.Hosts)),
chain.LoggerRouterOption(listenerLogger),
}
if !ignoreChain {
routerOpts = append(routerOpts,
chain.ChainRouterOption(chainGroup(cfg.Listener.Chain, cfg.Listener.ChainGroup)),
)
} }
listenOpts := []listener.Option{ listenOpts := []listener.Option{
listener.AddrOption(cfg.Addr), listener.AddrOption(cfg.Addr),
listener.RouterOption(chain.NewRouter(routerOpts...)),
listener.AutherOption(auther), listener.AutherOption(auther),
listener.AuthOption(auth_parser.Info(cfg.Listener.Auth)), listener.AuthOption(auth_parser.Info(cfg.Listener.Auth)),
listener.TLSConfigOption(tlsConfig), listener.TLSConfigOption(tlsConfig),
listener.AdmissionOption(admission.AdmissionGroup(admissions...)), listener.AdmissionOption(admission.AdmissionGroup(admissions...)),
listener.TrafficLimiterOption(registry.TrafficLimiterRegistry().Get(cfg.Limiter)), listener.TrafficLimiterOption(registry.TrafficLimiterRegistry().Get(cfg.Limiter)),
listener.ConnLimiterOption(registry.ConnLimiterRegistry().Get(cfg.CLimiter)), listener.ConnLimiterOption(registry.ConnLimiterRegistry().Get(cfg.CLimiter)),
listener.LoggerOption(listenerLogger),
listener.ServiceOption(cfg.Name), listener.ServiceOption(cfg.Name),
listener.ProxyProtocolOption(ppv), listener.ProxyProtocolOption(ppv),
listener.StatsOption(pStats), listener.StatsOption(pStats),
listener.NetnsOption(netnsIn),
listener.LoggerOption(listenerLogger),
} }
if !ignoreChain {
listenOpts = append(listenOpts, if netnsIn != "" {
listener.ChainOption(chainGroup(cfg.Listener.Chain, cfg.Listener.ChainGroup)), runtime.LockOSThread()
) defer runtime.UnlockOSThread()
originNs, err := netns.Get()
if err != nil {
return nil, fmt.Errorf("netns.Get(): %v", err)
}
defer netns.Set(originNs)
ns, err := netns.GetFromName(netnsIn)
if err != nil {
return nil, fmt.Errorf("netns.GetFromName(%s): %v", netnsIn, err)
}
defer ns.Close()
if err := netns.Set(ns); err != nil {
return nil, fmt.Errorf("netns.Set(%s): %v", netnsIn, err)
}
} }
var ln listener.Listener var ln listener.Listener
@ -205,10 +245,11 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
}) })
} }
routerOpts := []chain.RouterOption{ routerOpts = []chain.RouterOption{
chain.RetriesRouterOption(cfg.Handler.Retries), chain.RetriesRouterOption(cfg.Handler.Retries),
// chain.TimeoutRouterOption(10*time.Second), chain.TimeoutRouterOption(dialTimeout),
chain.InterfaceRouterOption(ifce), chain.InterfaceRouterOption(ifce),
chain.NetnsRouterOption(netnsOut),
chain.SockOptsRouterOption(sockOpts), chain.SockOptsRouterOption(sockOpts),
chain.ResolverRouterOption(registry.ResolverRegistry().Get(cfg.Resolver)), chain.ResolverRouterOption(registry.ResolverRegistry().Get(cfg.Resolver)),
chain.HostMapperRouterOption(registry.HostsRegistry().Get(cfg.Hosts)), chain.HostMapperRouterOption(registry.HostsRegistry().Get(cfg.Hosts)),
@ -220,12 +261,11 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
chain.ChainRouterOption(chainGroup(cfg.Handler.Chain, cfg.Handler.ChainGroup)), chain.ChainRouterOption(chainGroup(cfg.Handler.Chain, cfg.Handler.ChainGroup)),
) )
} }
router := chain.NewRouter(routerOpts...)
var h handler.Handler var h handler.Handler
if rf := registry.HandlerRegistry().Get(cfg.Handler.Type); rf != nil { if rf := registry.HandlerRegistry().Get(cfg.Handler.Type); rf != nil {
h = rf( h = rf(
handler.RouterOption(router), handler.RouterOption(chain.NewRouter(routerOpts...)),
handler.AutherOption(auther), handler.AutherOption(auther),
handler.AuthOption(auth_parser.Info(cfg.Handler.Auth)), handler.AuthOption(auth_parser.Info(cfg.Handler.Auth)),
handler.BypassOption(bypass.BypassGroup(bypass_parser.List(cfg.Bypass, cfg.Bypasses...)...)), handler.BypassOption(bypass.BypassGroup(bypass_parser.List(cfg.Bypass, cfg.Bypasses...)...)),
@ -235,6 +275,7 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
handler.ObserverOption(registry.ObserverRegistry().Get(cfg.Handler.Observer)), handler.ObserverOption(registry.ObserverRegistry().Get(cfg.Handler.Observer)),
handler.LoggerOption(handlerLogger), handler.LoggerOption(handlerLogger),
handler.ServiceOption(cfg.Name), handler.ServiceOption(cfg.Name),
handler.NetnsOption(netnsIn),
) )
} else { } else {
return nil, fmt.Errorf("unknown handler: %s", cfg.Handler.Type) return nil, fmt.Errorf("unknown handler: %s", cfg.Handler.Type)

View File

@ -44,9 +44,17 @@ func (c *directConnector) Connect(ctx context.Context, _ net.Conn, network, addr
return nil, err return nil, err
} }
var localAddr, remoteAddr string
if addr := conn.LocalAddr(); addr != nil {
localAddr = addr.String()
}
if addr := conn.RemoteAddr(); addr != nil {
remoteAddr = addr.String()
}
log := c.options.Logger.WithFields(map[string]any{ log := c.options.Logger.WithFields(map[string]any{
"remote": conn.RemoteAddr().String(), "remote": remoteAddr,
"local": conn.LocalAddr().String(), "local": localAddr,
"network": network, "network": network,
"address": address, "address": address,
}) })

View File

@ -69,6 +69,10 @@ func (c *udpRelayConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
if err = socksAddr.ParseFrom(addr.String()); err != nil { if err = socksAddr.ParseFrom(addr.String()); err != nil {
return return
} }
if socksAddr.Host == "" {
socksAddr.Type = gosocks5.AddrIPv4
socksAddr.Host = "127.0.0.1"
}
header := gosocks5.UDPHeader{ header := gosocks5.UDPHeader{
Addr: &socksAddr, Addr: &socksAddr,

View File

@ -130,6 +130,10 @@ func (c *socks5Connector) Connect(ctx context.Context, conn net.Conn, network, a
log.Error(err) log.Error(err)
return nil, err return nil, err
} }
if addr.Host == "" {
addr.Type = gosocks5.AddrIPv4
addr.Host = "127.0.0.1"
}
req := gosocks5.NewRequest(gosocks5.CmdConnect, &addr) req := gosocks5.NewRequest(gosocks5.CmdConnect, &addr)
log.Trace(req) log.Trace(req)
@ -201,12 +205,12 @@ func (c *socks5Connector) relayUDP(ctx context.Context, conn net.Conn, addr net.
} }
log.Trace(reply) log.Trace(reply)
log.Debugf("bind on: %v", reply.Addr)
if reply.Rep != gosocks5.Succeeded { if reply.Rep != gosocks5.Succeeded {
return nil, errors.New("get socks5 UDP tunnel failure") return nil, errors.New("get socks5 UDP tunnel failure")
} }
log.Debugf("bind on: %v", reply.Addr)
cc, err := opts.NetDialer.Dial(ctx, "udp", reply.Addr.String()) cc, err := opts.NetDialer.Dial(ctx, "udp", reply.Addr.String())
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -115,7 +115,7 @@ func (d *icmpDialer) initSession(ctx context.Context, addr net.Addr, conn net.Pa
} }
tlsCfg := d.options.TLSConfig tlsCfg := d.options.TLSConfig
tlsCfg.NextProtos = []string{"http/3", "quic/v1"} tlsCfg.NextProtos = []string{"h3", "quic/v1"}
session, err := quic.DialEarly(ctx, conn, addr, tlsCfg, quicConfig) session, err := quic.DialEarly(ctx, conn, addr, tlsCfg, quicConfig)
if err != nil { if err != nil {

View File

@ -114,7 +114,7 @@ func (d *quicDialer) initSession(ctx context.Context, addr net.Addr, conn net.Pa
} }
tlsCfg := d.options.TLSConfig tlsCfg := d.options.TLSConfig
tlsCfg.NextProtos = []string{"http/3", "quic/v1"} tlsCfg.NextProtos = []string{"h3", "quic/v1"}
session, err := quic.DialEarly(ctx, conn, addr, tlsCfg, quicConfig) session, err := quic.DialEarly(ctx, conn, addr, tlsCfg, quicConfig)
if err != nil { if err != nil {

48
dialer/wg/dialer.go Normal file
View File

@ -0,0 +1,48 @@
package wg
import (
"context"
"net"
"github.com/go-gost/core/dialer"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/x/registry"
)
func init() {
registry.DialerRegistry().Register("wg", NewDialer)
}
type wgDialer struct {
md metadata
logger logger.Logger
}
func NewDialer(opts ...dialer.Option) dialer.Dialer {
options := &dialer.Options{}
for _, opt := range opts {
opt(options)
}
return &wgDialer{
logger: options.Logger,
}
}
func (d *wgDialer) Init(md md.Metadata) (err error) {
return d.parseMetadata(md)
}
func (d *wgDialer) Dial(ctx context.Context, addr string, opts ...dialer.DialOption) (net.Conn, error) {
var options dialer.DialOptions
for _, opt := range opts {
opt(&options)
}
conn, err := options.NetDialer.Dial(ctx, "tcp", addr)
if err != nil {
d.logger.Error(err)
}
return conn, err
}

23
dialer/wg/metadata.go Normal file
View File

@ -0,0 +1,23 @@
package wg
import (
"time"
md "github.com/go-gost/core/metadata"
)
const (
dialTimeout = "dialTimeout"
)
const (
defaultDialTimeout = 5 * time.Second
)
type metadata struct {
dialTimeout time.Duration
}
func (d *wgDialer) parseMetadata(md md.Metadata) (err error) {
return
}

6
go.mod
View File

@ -9,9 +9,9 @@ require (
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/gin-contrib/cors v1.5.0 github.com/gin-contrib/cors v1.5.0
github.com/gin-gonic/gin v1.9.1 github.com/gin-gonic/gin v1.9.1
github.com/go-gost/core v0.0.0-20240508132029-8d554ddcf77c github.com/go-gost/core v0.0.0-20240704150322-30cc92870515
github.com/go-gost/gosocks4 v0.0.1 github.com/go-gost/gosocks4 v0.0.1
github.com/go-gost/gosocks5 v0.4.0 github.com/go-gost/gosocks5 v0.4.2
github.com/go-gost/plugin v0.0.0-20240103125338-9c84e29cb81a github.com/go-gost/plugin v0.0.0-20240103125338-9c84e29cb81a
github.com/go-gost/relay v0.5.0 github.com/go-gost/relay v0.5.0
github.com/go-gost/tls-dissector v0.0.2-0.20220408131628-aac992c27451 github.com/go-gost/tls-dissector v0.0.2-0.20220408131628-aac992c27451
@ -35,6 +35,7 @@ require (
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
github.com/spf13/viper v1.18.2 github.com/spf13/viper v1.18.2
github.com/vishvananda/netlink v1.1.0 github.com/vishvananda/netlink v1.1.0
github.com/vishvananda/netns v0.0.4
github.com/xtaci/kcp-go/v5 v5.6.5 github.com/xtaci/kcp-go/v5 v5.6.5
github.com/xtaci/smux v1.5.24 github.com/xtaci/smux v1.5.24
github.com/xtaci/tcpraw v1.2.25 github.com/xtaci/tcpraw v1.2.25
@ -106,7 +107,6 @@ require (
github.com/tjfoc/gmsm v1.4.1 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect github.com/ugorji/go/codec v1.2.11 // indirect
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
go.uber.org/mock v0.4.0 // indirect go.uber.org/mock v0.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.6.0 // indirect golang.org/x/arch v0.6.0 // indirect

11
go.sum
View File

@ -53,12 +53,12 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-gost/core v0.0.0-20240508132029-8d554ddcf77c h1:1ahtn+3bQB50at5ubWDOrA4yja8vWpWNrGSRaCztNWg= github.com/go-gost/core v0.0.0-20240704150322-30cc92870515 h1:i/zcDZtz00hcmRosvJgXmgJsdc4bC32PAvt2+8MUOEg=
github.com/go-gost/core v0.0.0-20240508132029-8d554ddcf77c/go.mod h1:j08tDHkFzk7dfOeLhl3RWsASdf9YWWRfWBUQqbQvx3A= github.com/go-gost/core v0.0.0-20240704150322-30cc92870515/go.mod h1:QmVAZIXIYBsX44Vehwug5RFnG2K3/Hz/uu/Y4QVhAY0=
github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2s= github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2s=
github.com/go-gost/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc= github.com/go-gost/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc=
github.com/go-gost/gosocks5 v0.4.0 h1:EIrOEkpJez4gwHrMa33frA+hHXJyevjp47thpMQsJzI= github.com/go-gost/gosocks5 v0.4.2 h1:IianxHTkACPqCwiOAT3MHoMdSUl+SEPSRu1ikawC1Pc=
github.com/go-gost/gosocks5 v0.4.0/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4= github.com/go-gost/gosocks5 v0.4.2/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4=
github.com/go-gost/plugin v0.0.0-20240103125338-9c84e29cb81a h1:ME7P1Brcg4C640DSPqlvQr7JuvvQfJ8QpmS3yCFlK3A= github.com/go-gost/plugin v0.0.0-20240103125338-9c84e29cb81a h1:ME7P1Brcg4C640DSPqlvQr7JuvvQfJ8QpmS3yCFlK3A=
github.com/go-gost/plugin v0.0.0-20240103125338-9c84e29cb81a/go.mod h1:qXr2Zm9Ex2ATqnWuNUzVZqySPMnuIihvblYZt4MlZLw= github.com/go-gost/plugin v0.0.0-20240103125338-9c84e29cb81a/go.mod h1:qXr2Zm9Ex2ATqnWuNUzVZqySPMnuIihvblYZt4MlZLw=
github.com/go-gost/relay v0.5.0 h1:JG1tgy/KWiVXS0ukuVXvbM0kbYuJTWxYpJ5JwzsCf/c= github.com/go-gost/relay v0.5.0 h1:JG1tgy/KWiVXS0ukuVXvbM0kbYuJTWxYpJ5JwzsCf/c=
@ -242,8 +242,9 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/xtaci/kcp-go/v5 v5.6.5 h1:oxGZNobj3OddrLzwdJYnR/waNgwrL98u02u0DWNHE3k= github.com/xtaci/kcp-go/v5 v5.6.5 h1:oxGZNobj3OddrLzwdJYnR/waNgwrL98u02u0DWNHE3k=
github.com/xtaci/kcp-go/v5 v5.6.5/go.mod h1:Qy3Zf2tWTdFdEs0E8JvhrX+39r5UDZoYac8anvud7/Q= github.com/xtaci/kcp-go/v5 v5.6.5/go.mod h1:Qy3Zf2tWTdFdEs0E8JvhrX+39r5UDZoYac8anvud7/Q=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=

View File

@ -23,13 +23,13 @@ import (
traffic "github.com/go-gost/core/limiter/traffic" traffic "github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata" md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer/stats"
ctxvalue "github.com/go-gost/x/ctx" ctxvalue "github.com/go-gost/x/ctx"
netpkg "github.com/go-gost/x/internal/net" netpkg "github.com/go-gost/x/internal/net"
stats_util "github.com/go-gost/x/internal/util/stats" stats_util "github.com/go-gost/x/internal/util/stats"
traffic_wrapper "github.com/go-gost/x/limiter/traffic/wrapper" traffic_wrapper "github.com/go-gost/x/limiter/traffic/wrapper"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
"github.com/go-gost/x/stats"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {
@ -161,14 +161,19 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
log.Debugf("%s >> %s", conn.RemoteAddr(), addr) log.Debugf("%s >> %s", conn.RemoteAddr(), addr)
resp := &http.Response{ resp := &http.Response{
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 1, ProtoMinor: 1,
Header: h.md.header, Header: h.md.header,
ContentLength: -1,
} }
if resp.Header == nil { if resp.Header == nil {
resp.Header = http.Header{} resp.Header = http.Header{}
} }
if resp.Header.Get("Proxy-Agent") == "" {
resp.Header.Set("Proxy-Agent", h.md.proxyAgent)
}
clientID, ok := h.authenticate(ctx, conn, req, resp, log) clientID, ok := h.authenticate(ctx, conn, req, resp, log)
if !ok { if !ok {
return nil return nil

View File

@ -10,7 +10,8 @@ import (
) )
const ( const (
defaultRealm = "gost" defaultRealm = "gost"
defaultProxyAgent = "gost/3.0"
) )
type metadata struct { type metadata struct {
@ -20,6 +21,7 @@ type metadata struct {
hash string hash string
authBasicRealm string authBasicRealm string
observePeriod time.Duration observePeriod time.Duration
proxyAgent string
} }
func (h *httpHandler) parseMetadata(md mdata.Metadata) error { func (h *httpHandler) parseMetadata(md mdata.Metadata) error {
@ -46,6 +48,11 @@ func (h *httpHandler) parseMetadata(md mdata.Metadata) error {
h.md.observePeriod = mdutil.GetDuration(md, "observePeriod") h.md.observePeriod = mdutil.GetDuration(md, "observePeriod")
h.md.proxyAgent = mdutil.GetString(md, "http.proxyAgent", "proxyAgent")
if h.md.proxyAgent == "" {
h.md.proxyAgent = defaultProxyAgent
}
return nil return nil
} }

View File

@ -23,14 +23,14 @@ import (
"github.com/go-gost/core/limiter/traffic" "github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata" md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer/stats"
ctxvalue "github.com/go-gost/x/ctx" ctxvalue "github.com/go-gost/x/ctx"
xio "github.com/go-gost/x/internal/io" xio "github.com/go-gost/x/internal/io"
netpkg "github.com/go-gost/x/internal/net" netpkg "github.com/go-gost/x/internal/net"
stats_util "github.com/go-gost/x/internal/util/stats" stats_util "github.com/go-gost/x/internal/util/stats"
"github.com/go-gost/x/limiter/traffic/wrapper" "github.com/go-gost/x/limiter/traffic/wrapper"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
"github.com/go-gost/x/stats"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -10,6 +10,7 @@ import (
"github.com/go-gost/core/listener" "github.com/go-gost/core/listener"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/relay" "github.com/go-gost/relay"
xnet "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/net/udp"
"github.com/go-gost/x/internal/util/mux" "github.com/go-gost/x/internal/util/mux"
relay_util "github.com/go-gost/x/internal/util/relay" relay_util "github.com/go-gost/x/internal/util/relay"
@ -50,7 +51,10 @@ func (h *relayHandler) bindTCP(ctx context.Context, conn net.Conn, network, addr
Status: relay.StatusOK, Status: relay.StatusOK,
} }
ln, err := net.Listen(network, address) // strict mode: if the port already in use, it will return error lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
ln, err := lc.Listen(ctx, network, address) // strict mode: if the port already in use, it will return error
if err != nil { if err != nil {
log.Error(err) log.Error(err)
resp.Status = relay.StatusServiceUnavailable resp.Status = relay.StatusServiceUnavailable
@ -129,10 +133,10 @@ func (h *relayHandler) bindUDP(ctx context.Context, conn net.Conn, network, addr
Status: relay.StatusOK, Status: relay.StatusOK,
} }
var pc net.PacketConn lc := xnet.ListenConfig{
var err error Netns: h.options.Netns,
bindAddr, _ := net.ResolveUDPAddr(network, address) }
pc, err = net.ListenUDP(network, bindAddr) pc, err := lc.ListenPacket(ctx, network, address)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
return err return err

View File

@ -10,13 +10,13 @@ import (
"github.com/go-gost/core/limiter/traffic" "github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/relay" "github.com/go-gost/relay"
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"
serial "github.com/go-gost/x/internal/util/serial" serial "github.com/go-gost/x/internal/util/serial"
"github.com/go-gost/x/limiter/traffic/wrapper" "github.com/go-gost/x/limiter/traffic/wrapper"
"github.com/go-gost/x/stats" stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
) )
func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) (err error) { func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) (err error) {

View File

@ -9,12 +9,12 @@ import (
"github.com/go-gost/core/limiter/traffic" "github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/relay" "github.com/go-gost/relay"
ctxvalue "github.com/go-gost/x/ctx" ctxvalue "github.com/go-gost/x/ctx"
netpkg "github.com/go-gost/x/internal/net" netpkg "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/limiter/traffic/wrapper" "github.com/go-gost/x/limiter/traffic/wrapper"
"github.com/go-gost/x/stats" stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
) )
func (h *relayHandler) handleForward(ctx context.Context, conn net.Conn, network string, log logger.Logger) error { func (h *relayHandler) handleForward(ctx context.Context, conn net.Conn, network string, log logger.Logger) error {

View File

@ -11,14 +11,14 @@ import (
"github.com/go-gost/core/limiter/traffic" "github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata" md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/gosocks4" "github.com/go-gost/gosocks4"
ctxvalue "github.com/go-gost/x/ctx" ctxvalue "github.com/go-gost/x/ctx"
netpkg "github.com/go-gost/x/internal/net" netpkg "github.com/go-gost/x/internal/net"
stats_util "github.com/go-gost/x/internal/util/stats" stats_util "github.com/go-gost/x/internal/util/stats"
"github.com/go-gost/x/limiter/traffic/wrapper" "github.com/go-gost/x/limiter/traffic/wrapper"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
"github.com/go-gost/x/stats"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
) )
var ( var (

View File

@ -9,6 +9,7 @@ import (
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/gosocks5" "github.com/go-gost/gosocks5"
netpkg "github.com/go-gost/x/internal/net" netpkg "github.com/go-gost/x/internal/net"
xnet "github.com/go-gost/x/internal/net"
) )
func (h *socks5Handler) handleBind(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error { func (h *socks5Handler) handleBind(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error {
@ -31,7 +32,10 @@ func (h *socks5Handler) handleBind(ctx context.Context, conn net.Conn, network,
} }
func (h *socks5Handler) bindLocal(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error { func (h *socks5Handler) bindLocal(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error {
ln, err := net.Listen(network, address) // strict mode: if the port already in use, it will return error lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
ln, err := lc.Listen(ctx, network, address) // strict mode: if the port already in use, it will return error
if err != nil { if err != nil {
log.Error(err) log.Error(err)
reply := gosocks5.NewReply(gosocks5.Failure, nil) reply := gosocks5.NewReply(gosocks5.Failure, nil)
@ -95,7 +99,7 @@ func (h *socks5Handler) serveBind(ctx context.Context, conn net.Conn, ln net.Lis
defer close(errc) defer close(errc)
defer pc1.Close() defer pc1.Close()
errc <- netpkg.Transport(conn, pc1) errc <- xnet.Transport(conn, pc1)
}() }()
return errc return errc

View File

@ -8,12 +8,12 @@ import (
"github.com/go-gost/core/limiter/traffic" "github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/gosocks5" "github.com/go-gost/gosocks5"
ctxvalue "github.com/go-gost/x/ctx" ctxvalue "github.com/go-gost/x/ctx"
netpkg "github.com/go-gost/x/internal/net" netpkg "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/limiter/traffic/wrapper" "github.com/go-gost/x/limiter/traffic/wrapper"
"github.com/go-gost/x/stats" stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
) )
func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error { func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error {

View File

@ -8,7 +8,7 @@ import (
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/gosocks5" "github.com/go-gost/gosocks5"
netpkg "github.com/go-gost/x/internal/net" xnet "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/internal/util/mux" "github.com/go-gost/x/internal/util/mux"
) )
@ -31,7 +31,10 @@ func (h *socks5Handler) handleMuxBind(ctx context.Context, conn net.Conn, networ
} }
func (h *socks5Handler) muxBindLocal(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error { func (h *socks5Handler) muxBindLocal(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error {
ln, err := net.Listen(network, address) // strict mode: if the port already in use, it will return error lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
ln, err := lc.Listen(ctx, network, address) // strict mode: if the port already in use, it will return error
if err != nil { if err != nil {
log.Error(err) log.Error(err)
reply := gosocks5.NewReply(gosocks5.Failure, nil) reply := gosocks5.NewReply(gosocks5.Failure, nil)
@ -125,7 +128,7 @@ func (h *socks5Handler) serveMuxBind(ctx context.Context, conn net.Conn, ln net.
t := time.Now() t := time.Now()
log.Debugf("%s <-> %s", c.LocalAddr(), c.RemoteAddr()) log.Debugf("%s <-> %s", c.LocalAddr(), c.RemoteAddr())
netpkg.Transport(sc, c) xnet.Transport(sc, c)
log.WithFields(map[string]any{"duration": time.Since(t)}). log.WithFields(map[string]any{"duration": time.Since(t)}).
Debugf("%s >-< %s", c.LocalAddr(), c.RemoteAddr()) Debugf("%s >-< %s", c.LocalAddr(), c.RemoteAddr())
}(rc) }(rc)

View File

@ -9,12 +9,13 @@ import (
"time" "time"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/gosocks5" "github.com/go-gost/gosocks5"
ctxvalue "github.com/go-gost/x/ctx" ctxvalue "github.com/go-gost/x/ctx"
xnet "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/net/udp"
"github.com/go-gost/x/internal/util/socks" "github.com/go-gost/x/internal/util/socks"
"github.com/go-gost/x/stats" stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
) )
func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, log logger.Logger) error { func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, log logger.Logger) error {
@ -29,7 +30,11 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, log logger
return reply.Write(conn) return reply.Write(conn)
} }
cc, err := net.ListenUDP("udp", nil) lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
laddr := &net.UDPAddr{IP: conn.LocalAddr().(*net.TCPAddr).IP, Port: 0} // use out-going interface's IP
cc, err := lc.ListenPacket(ctx, "udp", laddr.String())
if err != nil { if err != nil {
log.Error(err) log.Error(err)
reply := gosocks5.NewReply(gosocks5.Failure, nil) reply := gosocks5.NewReply(gosocks5.Failure, nil)
@ -41,8 +46,6 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, log logger
saddr := gosocks5.Addr{} saddr := gosocks5.Addr{}
saddr.ParseFrom(cc.LocalAddr().String()) saddr.ParseFrom(cc.LocalAddr().String())
saddr.Type = 0
saddr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String()) // replace the IP to the out-going interface's
reply := gosocks5.NewReply(gosocks5.Succeeded, &saddr) reply := gosocks5.NewReply(gosocks5.Succeeded, &saddr)
log.Trace(reply) log.Trace(reply)
if err := reply.Write(conn); err != nil { if err := reply.Write(conn); err != nil {
@ -70,17 +73,16 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, log logger
return err return err
} }
var lc net.PacketConn = cc
clientID := ctxvalue.ClientIDFromContext(ctx) clientID := ctxvalue.ClientIDFromContext(ctx)
if h.options.Observer != nil { if h.options.Observer != nil {
pstats := h.stats.Stats(string(clientID)) pstats := h.stats.Stats(string(clientID))
pstats.Add(stats.KindTotalConns, 1) pstats.Add(stats.KindTotalConns, 1)
pstats.Add(stats.KindCurrentConns, 1) pstats.Add(stats.KindCurrentConns, 1)
defer pstats.Add(stats.KindCurrentConns, -1) defer pstats.Add(stats.KindCurrentConns, -1)
lc = stats_wrapper.WrapPacketConn(lc, pstats) cc = stats_wrapper.WrapPacketConn(cc, pstats)
} }
r := udp.NewRelay(socks.UDPConn(lc, h.md.udpBufferSize), pc). r := udp.NewRelay(socks.UDPConn(cc, h.md.udpBufferSize), pc).
WithBypass(h.options.Bypass). WithBypass(h.options.Bypass).
WithLogger(log) WithLogger(log)
r.SetBufferSize(h.md.udpBufferSize) r.SetBufferSize(h.md.udpBufferSize)

View File

@ -2,16 +2,18 @@ package v5
import ( import (
"context" "context"
"errors"
"net" "net"
"time" "time"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/gosocks5" "github.com/go-gost/gosocks5"
ctxvalue "github.com/go-gost/x/ctx" ctxvalue "github.com/go-gost/x/ctx"
xnet "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/net/udp"
"github.com/go-gost/x/internal/util/socks" "github.com/go-gost/x/internal/util/socks"
"github.com/go-gost/x/stats" stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
) )
func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error { func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error {
@ -24,28 +26,52 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network
bindAddr = &net.UDPAddr{} bindAddr = &net.UDPAddr{}
} }
var pc net.PacketConn
// relay mode
if bindAddr.Port == 0 { if bindAddr.Port == 0 {
// relay mode
if !h.md.enableUDP { if !h.md.enableUDP {
reply := gosocks5.NewReply(gosocks5.NotAllowed, nil) reply := gosocks5.NewReply(gosocks5.NotAllowed, nil)
log.Trace(reply) log.Trace(reply)
log.Error("socks5: UDP relay is disabled") log.Error("socks5: UDP relay is disabled")
return reply.Write(conn) return reply.Write(conn)
} }
} else {
// BIND mode // obtain a udp connection
c, err := h.router.Dial(ctx, "udp", "") // UDP association
if err != nil {
log.Error(err)
return err
}
defer c.Close()
var ok bool
pc, ok = c.(net.PacketConn)
if !ok {
err := errors.New("socks5: wrong connection type")
log.Error(err)
return err
}
} else { // BIND mode
if !h.md.enableBind { if !h.md.enableBind {
reply := gosocks5.NewReply(gosocks5.NotAllowed, nil) reply := gosocks5.NewReply(gosocks5.NotAllowed, nil)
log.Trace(reply) log.Trace(reply)
log.Error("socks5: BIND is disabled") log.Error("socks5: BIND is disabled")
return reply.Write(conn) return reply.Write(conn)
} }
}
pc, err := net.ListenUDP(network, bindAddr) lc := xnet.ListenConfig{
if err != nil { Netns: h.options.Netns,
log.Error(err) }
return err var err error
pc, err = lc.ListenPacket(ctx, "udp", bindAddr.String())
if err != nil {
log.Error(err)
reply := gosocks5.NewReply(gosocks5.Failure, nil)
log.Trace(reply)
reply.Write(conn)
return err
}
} }
defer pc.Close() defer pc.Close()

View File

@ -1,8 +1,13 @@
package net package net
import ( import (
"context"
"fmt"
"net" "net"
"runtime"
"syscall" "syscall"
"github.com/vishvananda/netns"
) )
type SetBuffer interface { type SetBuffer interface {
@ -26,3 +31,57 @@ type SetDSCP interface {
func IsIPv4(address string) bool { func IsIPv4(address string) bool {
return address != "" && address[0] != ':' && address[0] != '[' return address != "" && address[0] != ':' && address[0] != '['
} }
type ListenConfig struct {
Netns string
net.ListenConfig
}
func (lc *ListenConfig) Listen(ctx context.Context, network, address string) (net.Listener, error) {
if lc.Netns != "" {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
originNs, err := netns.Get()
if err != nil {
return nil, fmt.Errorf("netns.Get(): %v", err)
}
defer netns.Set(originNs)
ns, err := netns.GetFromName(lc.Netns)
if err != nil {
return nil, fmt.Errorf("netns.GetFromName(%s): %v", lc.Netns, err)
}
defer ns.Close()
if err := netns.Set(ns); err != nil {
return nil, fmt.Errorf("netns.Set(%s): %v", lc.Netns, err)
}
}
return lc.ListenConfig.Listen(ctx, network, address)
}
func (lc *ListenConfig) ListenPacket(ctx context.Context, network, address string) (net.PacketConn, error) {
if lc.Netns != "" {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
originNs, err := netns.Get()
if err != nil {
return nil, fmt.Errorf("netns.Get(): %v", err)
}
defer netns.Set(originNs)
ns, err := netns.GetFromName(lc.Netns)
if err != nil {
return nil, fmt.Errorf("netns.GetFromName(%s): %v", lc.Netns, err)
}
defer ns.Close()
if err := netns.Set(ns); err != nil {
return nil, fmt.Errorf("netns.Set(%s): %v", lc.Netns, err)
}
}
return lc.ListenConfig.ListenPacket(ctx, network, address)
}

View File

@ -4,7 +4,7 @@ import (
"sync" "sync"
"github.com/go-gost/core/observer" "github.com/go-gost/core/observer"
"github.com/go-gost/x/stats" "github.com/go-gost/core/observer/stats"
) )
type HandlerStats struct { type HandlerStats struct {

View File

@ -3,7 +3,7 @@ package tls
import ( import (
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"errors" "fmt"
"net" "net"
"os" "os"
"strings" "strings"
@ -234,7 +234,7 @@ func loadCA(caFile string) (cp *x509.CertPool, err error) {
return nil, err return nil, err
} }
if !cp.AppendCertsFromPEM(data) { if !cp.AppendCertsFromPEM(data) {
return nil, errors.New("AppendCertsFromPEM failed") return nil, fmt.Errorf("loadCA %s: AppendCertsFromPEM failed", caFile)
} }
return return
} }

View File

@ -16,8 +16,8 @@ import (
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata" md "github.com/go-gost/core/metadata"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"github.com/miekg/dns" "github.com/miekg/dns"
) )

View File

@ -16,8 +16,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"github.com/pion/dtls/v2" "github.com/pion/dtls/v2"
) )

View File

@ -11,8 +11,8 @@ import (
xnet "github.com/go-gost/x/internal/net" xnet "github.com/go-gost/x/internal/net"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"github.com/xtaci/tcpraw" "github.com/xtaci/tcpraw"
) )

View File

@ -15,8 +15,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive" "google.golang.org/grpc/keepalive"

View File

@ -18,8 +18,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"golang.org/x/net/http2" "golang.org/x/net/http2"
"golang.org/x/net/http2/h2c" "golang.org/x/net/http2/h2c"
) )

View File

@ -17,8 +17,8 @@ import (
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
mdx "github.com/go-gost/x/metadata" mdx "github.com/go-gost/x/metadata"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"golang.org/x/net/http2" "golang.org/x/net/http2"
) )

View File

@ -11,8 +11,8 @@ import (
pht_util "github.com/go-gost/x/internal/util/pht" pht_util "github.com/go-gost/x/internal/util/pht"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"github.com/quic-go/quic-go" "github.com/quic-go/quic-go"
) )

View File

@ -13,8 +13,8 @@ import (
wt_util "github.com/go-gost/x/internal/util/wt" wt_util "github.com/go-gost/x/internal/util/wt"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"github.com/quic-go/quic-go" "github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/http3" "github.com/quic-go/quic-go/http3"
wt "github.com/quic-go/webtransport-go" wt "github.com/quic-go/webtransport-go"

View File

@ -11,8 +11,8 @@ import (
icmp_pkg "github.com/go-gost/x/internal/util/icmp" icmp_pkg "github.com/go-gost/x/internal/util/icmp"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"github.com/quic-go/quic-go" "github.com/quic-go/quic-go"
"golang.org/x/net/icmp" "golang.org/x/net/icmp"
) )
@ -73,7 +73,7 @@ func (l *icmpListener) Init(md md.Metadata) (err error) {
} }
tlsCfg := l.options.TLSConfig tlsCfg := l.options.TLSConfig
tlsCfg.NextProtos = []string{"http/3", "quic/v1"} tlsCfg.NextProtos = []string{"h3", "quic/v1"}
ln, err := quic.ListenEarly(conn, tlsCfg, config) ln, err := quic.ListenEarly(conn, tlsCfg, config)
if err != nil { if err != nil {

View File

@ -12,8 +12,8 @@ import (
kcp_util "github.com/go-gost/x/internal/util/kcp" kcp_util "github.com/go-gost/x/internal/util/kcp"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"github.com/xtaci/kcp-go/v5" "github.com/xtaci/kcp-go/v5"
"github.com/xtaci/smux" "github.com/xtaci/smux"
"github.com/xtaci/tcpraw" "github.com/xtaci/tcpraw"

View File

@ -15,8 +15,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -16,8 +16,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -19,8 +19,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )

View File

@ -14,8 +14,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -14,8 +14,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -13,8 +13,8 @@ import (
pht_util "github.com/go-gost/x/internal/util/pht" pht_util "github.com/go-gost/x/internal/util/pht"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -12,8 +12,8 @@ import (
quic_util "github.com/go-gost/x/internal/util/quic" quic_util "github.com/go-gost/x/internal/util/quic"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"github.com/quic-go/quic-go" "github.com/quic-go/quic-go"
) )
@ -82,7 +82,7 @@ func (l *quicListener) Init(md md.Metadata) (err error) {
} }
tlsCfg := l.options.TLSConfig tlsCfg := l.options.TLSConfig
tlsCfg.NextProtos = []string{"http/3", "quic/v1"} tlsCfg.NextProtos = []string{"h3", "quic/v1"}
ln, err := quic.ListenEarly(conn, tlsCfg, config) ln, err := quic.ListenEarly(conn, tlsCfg, config)
if err != nil { if err != nil {

View File

@ -14,8 +14,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -9,8 +9,8 @@ import (
admission "github.com/go-gost/x/admission/wrapper" admission "github.com/go-gost/x/admission/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -14,8 +14,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {
@ -60,10 +60,10 @@ func (l *rtcpListener) Init(md md.Metadata) (err error) {
l.laddr = &bindAddr{addr: l.options.Addr} l.laddr = &bindAddr{addr: l.options.Addr}
} }
l.router = chain.NewRouter( l.router = l.options.Router
chain.ChainRouterOption(l.options.Chain), if l.router == nil {
chain.LoggerRouterOption(l.logger), l.router = chain.NewRouter(chain.LoggerRouterOption(l.logger))
) }
return return
} }

View File

@ -13,8 +13,8 @@ import (
xnet "github.com/go-gost/x/internal/net" xnet "github.com/go-gost/x/internal/net"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {
@ -60,10 +60,10 @@ func (l *rudpListener) Init(md md.Metadata) (err error) {
l.laddr = &bindAddr{addr: l.options.Addr} l.laddr = &bindAddr{addr: l.options.Addr}
} }
l.router = chain.NewRouter( l.router = l.options.Router
chain.ChainRouterOption(l.options.Chain), if l.router == nil {
chain.LoggerRouterOption(l.logger), l.router = chain.NewRouter(chain.LoggerRouterOption(l.logger))
) }
return return
} }

View File

@ -11,8 +11,8 @@ import (
serial "github.com/go-gost/x/internal/util/serial" serial "github.com/go-gost/x/internal/util/serial"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -16,8 +16,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )

View File

@ -18,9 +18,9 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
stats "github.com/go-gost/x/stats/wrapper"
) )
// Applicable SSH Request types for Port Forwarding - RFC 4254 7.X // Applicable SSH Request types for Port Forwarding - RFC 4254 7.X

View File

@ -12,8 +12,8 @@ import (
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
mdx "github.com/go-gost/x/metadata" mdx "github.com/go-gost/x/metadata"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -14,8 +14,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -15,8 +15,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -13,8 +13,8 @@ import (
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
mdx "github.com/go-gost/x/metadata" mdx "github.com/go-gost/x/metadata"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -11,8 +11,8 @@ import (
xnet "github.com/go-gost/x/internal/net" xnet "github.com/go-gost/x/internal/net"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -10,8 +10,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
) )
func init() { func init() {

View File

@ -18,8 +18,8 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper" limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry" "github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )

View File

@ -6,10 +6,10 @@ import (
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/core/observer" "github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/plugin/observer/proto" "github.com/go-gost/plugin/observer/proto"
"github.com/go-gost/x/internal/plugin" "github.com/go-gost/x/internal/plugin"
"github.com/go-gost/x/service" "github.com/go-gost/x/service"
"github.com/go-gost/x/stats"
"google.golang.org/grpc" "google.golang.org/grpc"
) )

View File

@ -10,9 +10,9 @@ import (
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/core/observer" "github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/x/internal/plugin" "github.com/go-gost/x/internal/plugin"
"github.com/go-gost/x/service" "github.com/go-gost/x/service"
"github.com/go-gost/x/stats"
) )
type observeRequest struct { type observeRequest struct {

View File

@ -7,9 +7,9 @@ import (
"syscall" "syscall"
"github.com/go-gost/core/metadata" "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer/stats"
xnet "github.com/go-gost/x/internal/net" xnet "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/net/udp"
"github.com/go-gost/x/stats"
) )
var ( var (

View File

@ -3,7 +3,7 @@ package wrapper
import ( import (
"io" "io"
"github.com/go-gost/x/stats" "github.com/go-gost/core/observer/stats"
) )
// readWriter is an io.ReadWriter with Stats. // readWriter is an io.ReadWriter with Stats.

View File

@ -3,7 +3,7 @@ package wrapper
import ( import (
"net" "net"
"github.com/go-gost/x/stats" "github.com/go-gost/core/observer/stats"
) )
type listener struct { type listener struct {

View File

@ -15,11 +15,11 @@ import (
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/core/metrics" "github.com/go-gost/core/metrics"
"github.com/go-gost/core/observer" "github.com/go-gost/core/observer"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/core/recorder" "github.com/go-gost/core/recorder"
"github.com/go-gost/core/service" "github.com/go-gost/core/service"
ctxvalue "github.com/go-gost/x/ctx" ctxvalue "github.com/go-gost/x/ctx"
xmetrics "github.com/go-gost/x/metrics" xmetrics "github.com/go-gost/x/metrics"
"github.com/go-gost/x/stats"
"github.com/rs/xid" "github.com/rs/xid"
) )

View File

@ -4,7 +4,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/go-gost/x/stats" "github.com/go-gost/core/observer/stats"
) )
const ( const (

View File

@ -1,93 +0,0 @@
package stats
import (
"sync/atomic"
"github.com/go-gost/core/observer"
)
type Kind int
const (
KindTotalConns Kind = 1
KindCurrentConns Kind = 2
KindInputBytes Kind = 3
KindOutputBytes Kind = 4
KindTotalErrs Kind = 5
)
type Stats struct {
updated atomic.Bool
totalConns atomic.Uint64
currentConns atomic.Int64
inputBytes atomic.Uint64
outputBytes atomic.Uint64
totalErrs atomic.Uint64
}
func (s *Stats) Add(kind Kind, n int64) {
if s == nil {
return
}
switch kind {
case KindTotalConns:
if n > 0 {
s.totalConns.Add(uint64(n))
}
case KindCurrentConns:
s.currentConns.Add(n)
case KindInputBytes:
if n > 0 {
s.inputBytes.Add(uint64(n))
}
case KindOutputBytes:
if n > 0 {
s.outputBytes.Add(uint64(n))
}
case KindTotalErrs:
if n > 0 {
s.totalErrs.Add(uint64(n))
}
}
s.updated.Store(true)
}
func (s *Stats) Get(kind Kind) uint64 {
if s == nil {
return 0
}
switch kind {
case KindTotalConns:
return s.totalConns.Load()
case KindCurrentConns:
return uint64(s.currentConns.Load())
case KindInputBytes:
return s.inputBytes.Load()
case KindOutputBytes:
return s.outputBytes.Load()
case KindTotalErrs:
return s.totalErrs.Load()
}
return 0
}
func (s *Stats) IsUpdated() bool {
return s.updated.Swap(false)
}
type StatsEvent struct {
Kind string
Service string
Client string
TotalConns uint64
CurrentConns uint64
InputBytes uint64
OutputBytes uint64
TotalErrs uint64
}
func (StatsEvent) Type() observer.EventType {
return observer.EventStats
}