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"
"github.com/gin-gonic/gin"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/x/config"
"github.com/go-gost/x/registry"
"github.com/go-gost/x/service"
"github.com/go-gost/x/stats"
)
type serviceStatus interface {

View File

@ -487,6 +487,7 @@ type HopConfig struct {
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
Metadata map[string]any `yaml:",omitempty" json:"metadata,omitempty"`
}
type NodeConfig struct {
@ -500,6 +501,7 @@ type NodeConfig struct {
Connector *ConnectorConfig `yaml:",omitempty" json:"connector,omitempty"`
Dialer *DialerConfig `yaml:",omitempty" json:"dialer,omitempty"`
Interface string `yaml:",omitempty" json:"interface,omitempty"`
Netns string `yaml:",omitempty" json:"netns,omitempty"`
SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,omitempty"`
Filter *NodeFilterConfig `yaml:",omitempty" json:"filter,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/hop"
"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/parsing"
bypass_parser "github.com/go-gost/x/config/parsing/bypass"
node_parser "github.com/go-gost/x/config/parsing/node"
selector_parser "github.com/go-gost/x/config/parsing/selector"
@ -16,6 +18,7 @@ import (
hop_plugin "github.com/go-gost/x/hop/plugin"
"github.com/go-gost/x/internal/loader"
"github.com/go-gost/x/internal/plugin"
"github.com/go-gost/x/metadata"
)
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
for _, v := range cfg.Nodes {
if v == nil {
@ -60,8 +73,12 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) {
v.Hosts = cfg.Hosts
}
if v.Interface == "" {
v.Interface = cfg.Interface
v.Interface = ifce
}
if v.Netns == "" {
v.Netns = netns
}
if v.SockOpts == nil {
v.SockOpts = cfg.SockOpts
}

View File

@ -5,7 +5,6 @@ import (
"net"
"regexp"
"strings"
"time"
"github.com/go-gost/core/bypass"
"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,
chain.AddrTransportOption(cfg.Addr),
chain.InterfaceTransportOption(cfg.Interface),
chain.NetnsTransportOption(cfg.Netns),
chain.SockOptsTransportOption(sockOpts),
chain.TimeoutTransportOption(10*time.Second),
)
opts := []chain.NodeOption{

View File

@ -2,6 +2,7 @@ package service
import (
"fmt"
"runtime"
"strings"
"time"
@ -14,6 +15,7 @@ import (
"github.com/go-gost/core/listener"
"github.com/go-gost/core/logger"
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/selector"
"github.com/go-gost/core/service"
@ -31,7 +33,7 @@ import (
"github.com/go-gost/x/metadata"
"github.com/go-gost/x/registry"
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) {
@ -61,17 +63,13 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
"handler": cfg.Handler.Type,
})
listenerLogger := serviceLogger.WithFields(map[string]any{
"kind": "listener",
})
tlsCfg := cfg.Listener.TLS
if tlsCfg == nil {
tlsCfg = &config.TLSConfig{}
}
tlsConfig, err := tls_util.LoadServerConfig(tlsCfg)
if err != nil {
listenerLogger.Error(err)
serviceLogger.Error(err)
return nil, err
}
if tlsConfig == nil {
@ -104,6 +102,8 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
var ignoreChain bool
var pStats *stats.Stats
var observePeriod time.Duration
var netnsIn, netnsOut string
var dialTimeout time.Duration
if cfg.Metadata != nil {
md := metadata.NewMetadata(cfg.Metadata)
ppv = mdutil.GetInt(md, parsing.MDKeyProxyProtocol)
@ -125,25 +125,65 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
pStats = &stats.Stats{}
}
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{
listener.AddrOption(cfg.Addr),
listener.RouterOption(chain.NewRouter(routerOpts...)),
listener.AutherOption(auther),
listener.AuthOption(auth_parser.Info(cfg.Listener.Auth)),
listener.TLSConfigOption(tlsConfig),
listener.AdmissionOption(admission.AdmissionGroup(admissions...)),
listener.TrafficLimiterOption(registry.TrafficLimiterRegistry().Get(cfg.Limiter)),
listener.ConnLimiterOption(registry.ConnLimiterRegistry().Get(cfg.CLimiter)),
listener.LoggerOption(listenerLogger),
listener.ServiceOption(cfg.Name),
listener.ProxyProtocolOption(ppv),
listener.StatsOption(pStats),
listener.NetnsOption(netnsIn),
listener.LoggerOption(listenerLogger),
}
if netnsIn != "" {
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)
}
if !ignoreChain {
listenOpts = append(listenOpts,
listener.ChainOption(chainGroup(cfg.Listener.Chain, cfg.Listener.ChainGroup)),
)
}
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.TimeoutRouterOption(10*time.Second),
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)),
@ -220,12 +261,11 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
chain.ChainRouterOption(chainGroup(cfg.Handler.Chain, cfg.Handler.ChainGroup)),
)
}
router := chain.NewRouter(routerOpts...)
var h handler.Handler
if rf := registry.HandlerRegistry().Get(cfg.Handler.Type); rf != nil {
h = rf(
handler.RouterOption(router),
handler.RouterOption(chain.NewRouter(routerOpts...)),
handler.AutherOption(auther),
handler.AuthOption(auth_parser.Info(cfg.Handler.Auth)),
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.LoggerOption(handlerLogger),
handler.ServiceOption(cfg.Name),
handler.NetnsOption(netnsIn),
)
} else {
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
}
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{
"remote": conn.RemoteAddr().String(),
"local": conn.LocalAddr().String(),
"remote": remoteAddr,
"local": localAddr,
"network": network,
"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 {
return
}
if socksAddr.Host == "" {
socksAddr.Type = gosocks5.AddrIPv4
socksAddr.Host = "127.0.0.1"
}
header := gosocks5.UDPHeader{
Addr: &socksAddr,

View File

@ -130,6 +130,10 @@ func (c *socks5Connector) Connect(ctx context.Context, conn net.Conn, network, a
log.Error(err)
return nil, err
}
if addr.Host == "" {
addr.Type = gosocks5.AddrIPv4
addr.Host = "127.0.0.1"
}
req := gosocks5.NewRequest(gosocks5.CmdConnect, &addr)
log.Trace(req)
@ -201,12 +205,12 @@ func (c *socks5Connector) relayUDP(ctx context.Context, conn net.Conn, addr net.
}
log.Trace(reply)
log.Debugf("bind on: %v", reply.Addr)
if reply.Rep != gosocks5.Succeeded {
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())
if err != nil {
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.NextProtos = []string{"http/3", "quic/v1"}
tlsCfg.NextProtos = []string{"h3", "quic/v1"}
session, err := quic.DialEarly(ctx, conn, addr, tlsCfg, quicConfig)
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.NextProtos = []string{"http/3", "quic/v1"}
tlsCfg.NextProtos = []string{"h3", "quic/v1"}
session, err := quic.DialEarly(ctx, conn, addr, tlsCfg, quicConfig)
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/gin-contrib/cors v1.5.0
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/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/relay v0.5.0
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/spf13/viper v1.18.2
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/smux v1.5.24
github.com/xtaci/tcpraw v1.2.25
@ -106,7 +107,6 @@ require (
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // 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/multierr v1.11.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-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
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-20240508132029-8d554ddcf77c/go.mod h1:j08tDHkFzk7dfOeLhl3RWsASdf9YWWRfWBUQqbQvx3A=
github.com/go-gost/core v0.0.0-20240704150322-30cc92870515 h1:i/zcDZtz00hcmRosvJgXmgJsdc4bC32PAvt2+8MUOEg=
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/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc=
github.com/go-gost/gosocks5 v0.4.0 h1:EIrOEkpJez4gwHrMa33frA+hHXJyevjp47thpMQsJzI=
github.com/go-gost/gosocks5 v0.4.0/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4=
github.com/go-gost/gosocks5 v0.4.2 h1:IianxHTkACPqCwiOAT3MHoMdSUl+SEPSRu1ikawC1Pc=
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/go.mod h1:qXr2Zm9Ex2ATqnWuNUzVZqySPMnuIihvblYZt4MlZLw=
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/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
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.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/go.mod h1:Qy3Zf2tWTdFdEs0E8JvhrX+39r5UDZoYac8anvud7/Q=
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"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer/stats"
ctxvalue "github.com/go-gost/x/ctx"
netpkg "github.com/go-gost/x/internal/net"
stats_util "github.com/go-gost/x/internal/util/stats"
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/stats"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
)
func init() {
@ -164,11 +164,16 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
ProtoMajor: 1,
ProtoMinor: 1,
Header: h.md.header,
ContentLength: -1,
}
if resp.Header == nil {
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)
if !ok {
return nil

View File

@ -11,6 +11,7 @@ import (
const (
defaultRealm = "gost"
defaultProxyAgent = "gost/3.0"
)
type metadata struct {
@ -20,6 +21,7 @@ type metadata struct {
hash string
authBasicRealm string
observePeriod time.Duration
proxyAgent string
}
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.proxyAgent = mdutil.GetString(md, "http.proxyAgent", "proxyAgent")
if h.md.proxyAgent == "" {
h.md.proxyAgent = defaultProxyAgent
}
return nil
}

View File

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

View File

@ -10,6 +10,7 @@ import (
"github.com/go-gost/core/listener"
"github.com/go-gost/core/logger"
"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/util/mux"
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,
}
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 {
log.Error(err)
resp.Status = relay.StatusServiceUnavailable
@ -129,10 +133,10 @@ func (h *relayHandler) bindUDP(ctx context.Context, conn net.Conn, network, addr
Status: relay.StatusOK,
}
var pc net.PacketConn
var err error
bindAddr, _ := net.ResolveUDPAddr(network, address)
pc, err = net.ListenUDP(network, bindAddr)
lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
pc, err := lc.ListenPacket(ctx, network, address)
if err != nil {
log.Error(err)
return err

View File

@ -10,13 +10,13 @@ import (
"github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/relay"
ctxvalue "github.com/go-gost/x/ctx"
xnet "github.com/go-gost/x/internal/net"
serial "github.com/go-gost/x/internal/util/serial"
"github.com/go-gost/x/limiter/traffic/wrapper"
"github.com/go-gost/x/stats"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
)
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/logger"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/relay"
ctxvalue "github.com/go-gost/x/ctx"
netpkg "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/limiter/traffic/wrapper"
"github.com/go-gost/x/stats"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
)
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/logger"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/gosocks4"
ctxvalue "github.com/go-gost/x/ctx"
netpkg "github.com/go-gost/x/internal/net"
stats_util "github.com/go-gost/x/internal/util/stats"
"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/stats"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
)
var (

View File

@ -9,6 +9,7 @@ import (
"github.com/go-gost/core/logger"
"github.com/go-gost/gosocks5"
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 {
@ -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 {
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 {
log.Error(err)
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 pc1.Close()
errc <- netpkg.Transport(conn, pc1)
errc <- xnet.Transport(conn, pc1)
}()
return errc

View File

@ -8,12 +8,12 @@ import (
"github.com/go-gost/core/limiter/traffic"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/gosocks5"
ctxvalue "github.com/go-gost/x/ctx"
netpkg "github.com/go-gost/x/internal/net"
"github.com/go-gost/x/limiter/traffic/wrapper"
"github.com/go-gost/x/stats"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
)
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/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"
)
@ -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 {
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 {
log.Error(err)
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()
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)}).
Debugf("%s >-< %s", c.LocalAddr(), c.RemoteAddr())
}(rc)

View File

@ -9,12 +9,13 @@ import (
"time"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/gosocks5"
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/util/socks"
"github.com/go-gost/x/stats"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
)
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)
}
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 {
log.Error(err)
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.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)
log.Trace(reply)
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
}
var lc net.PacketConn = cc
clientID := ctxvalue.ClientIDFromContext(ctx)
if h.options.Observer != nil {
pstats := h.stats.Stats(string(clientID))
pstats.Add(stats.KindTotalConns, 1)
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).
WithLogger(log)
r.SetBufferSize(h.md.udpBufferSize)

View File

@ -2,16 +2,18 @@ package v5
import (
"context"
"errors"
"net"
"time"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
"github.com/go-gost/gosocks5"
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/util/socks"
"github.com/go-gost/x/stats"
stats_wrapper "github.com/go-gost/x/stats/wrapper"
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
)
func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error {
@ -24,29 +26,53 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network
bindAddr = &net.UDPAddr{}
}
if bindAddr.Port == 0 {
var pc net.PacketConn
// relay mode
if bindAddr.Port == 0 {
if !h.md.enableUDP {
reply := gosocks5.NewReply(gosocks5.NotAllowed, nil)
log.Trace(reply)
log.Error("socks5: UDP relay is disabled")
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 {
reply := gosocks5.NewReply(gosocks5.NotAllowed, nil)
log.Trace(reply)
log.Error("socks5: BIND is disabled")
return reply.Write(conn)
}
}
pc, err := net.ListenUDP(network, bindAddr)
lc := xnet.ListenConfig{
Netns: h.options.Netns,
}
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()
saddr := gosocks5.Addr{}

View File

@ -1,8 +1,13 @@
package net
import (
"context"
"fmt"
"net"
"runtime"
"syscall"
"github.com/vishvananda/netns"
)
type SetBuffer interface {
@ -26,3 +31,57 @@ type SetDSCP interface {
func IsIPv4(address string) bool {
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"
"github.com/go-gost/core/observer"
"github.com/go-gost/x/stats"
"github.com/go-gost/core/observer/stats"
)
type HandlerStats struct {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -13,8 +13,8 @@ import (
wt_util "github.com/go-gost/x/internal/util/wt"
limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"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/http3"
wt "github.com/quic-go/webtransport-go"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,9 +18,9 @@ import (
climiter "github.com/go-gost/x/limiter/conn/wrapper"
limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry"
"golang.org/x/crypto/ssh"
stats "github.com/go-gost/x/stats/wrapper"
)
// 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"
mdx "github.com/go-gost/x/metadata"
metrics "github.com/go-gost/x/metrics/wrapper"
stats "github.com/go-gost/x/observer/stats/wrapper"
"github.com/go-gost/x/registry"
stats "github.com/go-gost/x/stats/wrapper"
)
func init() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,9 +10,9 @@ import (
"github.com/go-gost/core/logger"
"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/service"
"github.com/go-gost/x/stats"
)
type observeRequest struct {

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@ import (
"sync"
"time"
"github.com/go-gost/x/stats"
"github.com/go-gost/core/observer/stats"
)
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
}