diff --git a/config/parsing/hop/parse.go b/config/parsing/hop/parse.go index 6bab821..3fb9dc5 100644 --- a/config/parsing/hop/parse.go +++ b/config/parsing/hop/parse.go @@ -67,15 +67,17 @@ func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) { } if v.Connector == nil { - v.Connector = &config.ConnectorConfig{ - Type: "http", - } + v.Connector = &config.ConnectorConfig{} + } + if strings.TrimSpace(v.Connector.Type) == "" { + v.Connector.Type = "http" } if v.Dialer == nil { - v.Dialer = &config.DialerConfig{ - Type: "tcp", - } + v.Dialer = &config.DialerConfig{} + } + if strings.TrimSpace(v.Dialer.Type) == "" { + v.Dialer.Type = "tcp" } node, err := node_parser.ParseNode(cfg.Name, v, log) diff --git a/config/parsing/service/parse.go b/config/parsing/service/parse.go index 572e1e3..3554256 100644 --- a/config/parsing/service/parse.go +++ b/config/parsing/service/parse.go @@ -3,6 +3,7 @@ package service import ( "fmt" "strings" + "time" "github.com/go-gost/core/admission" "github.com/go-gost/core/auth" @@ -37,14 +38,14 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) { if cfg.Listener == nil { cfg.Listener = &config.ListenerConfig{} } - if lt := strings.TrimSpace(cfg.Listener.Type); lt == "" { + if strings.TrimSpace(cfg.Listener.Type) == "" { cfg.Listener.Type = "tcp" } if cfg.Handler == nil { cfg.Handler = &config.HandlerConfig{} } - if ht := strings.TrimSpace(cfg.Handler.Type); ht == "" { + if strings.TrimSpace(cfg.Handler.Type) == "" { cfg.Handler.Type = "auto" } @@ -102,6 +103,7 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) { var preUp, preDown, postUp, postDown []string var ignoreChain bool var pStats *stats.Stats + var observePeriod time.Duration if cfg.Metadata != nil { md := metadata.NewMetadata(cfg.Metadata) ppv = mdutil.GetInt(md, parsing.MDKeyProxyProtocol) @@ -122,6 +124,7 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) { if mdutil.GetBool(md, parsing.MDKeyEnableStats) { pStats = &stats.Stats{} } + observePeriod = mdutil.GetDuration(md, "observePeriod") } listenOpts := []listener.Option{ @@ -263,6 +266,7 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) { xservice.RecordersOption(recorders...), xservice.StatsOption(pStats), xservice.ObserverOption(registry.ObserverRegistry().Get(cfg.Observer)), + xservice.ObservePeriodOption(observePeriod), xservice.LoggerOption(serviceLogger), ) diff --git a/handler/http/handler.go b/handler/http/handler.go index b6887be..0473e22 100644 --- a/handler/http/handler.go +++ b/handler/http/handler.go @@ -452,7 +452,11 @@ func (h *httpHandler) observeStats(ctx context.Context) { return } - ticker := time.NewTicker(5 * time.Second) + d := h.md.observePeriod + if d < time.Millisecond { + d = 5 * time.Second + } + ticker := time.NewTicker(d) defer ticker.Stop() for { diff --git a/handler/http/metadata.go b/handler/http/metadata.go index fd9af19..4f7b4e1 100644 --- a/handler/http/metadata.go +++ b/handler/http/metadata.go @@ -3,6 +3,7 @@ package http import ( "net/http" "strings" + "time" mdata "github.com/go-gost/core/metadata" mdutil "github.com/go-gost/core/metadata/util" @@ -18,20 +19,11 @@ type metadata struct { header http.Header hash string authBasicRealm string + observePeriod time.Duration } func (h *httpHandler) parseMetadata(md mdata.Metadata) error { - const ( - header = "header" - probeResistKey = "probeResistance" - probeResistKeyX = "probe_resist" - knock = "knock" - enableUDP = "udp" - hash = "hash" - authBasicRealm = "authBasicRealm" - ) - - if m := mdutil.GetStringMapString(md, header); len(m) > 0 { + if m := mdutil.GetStringMapString(md, "http.header", "header"); len(m) > 0 { hd := http.Header{} for k, v := range m { hd.Add(k, v) @@ -39,22 +31,20 @@ func (h *httpHandler) parseMetadata(md mdata.Metadata) error { h.md.header = hd } - pr := mdutil.GetString(md, probeResistKey) - if pr == "" { - pr = mdutil.GetString(md, probeResistKeyX) - } - if pr != "" { + if pr := mdutil.GetString(md, "probeResist", "probe_resist"); pr != "" { if ss := strings.SplitN(pr, ":", 2); len(ss) == 2 { h.md.probeResistance = &probeResistance{ Type: ss[0], Value: ss[1], - Knock: mdutil.GetString(md, knock), + Knock: mdutil.GetString(md, "knock"), } } } - h.md.enableUDP = mdutil.GetBool(md, enableUDP) - h.md.hash = mdutil.GetString(md, hash) - h.md.authBasicRealm = mdutil.GetString(md, authBasicRealm) + h.md.enableUDP = mdutil.GetBool(md, "udp") + h.md.hash = mdutil.GetString(md, "hash") + h.md.authBasicRealm = mdutil.GetString(md, "authBasicRealm") + + h.md.observePeriod = mdutil.GetDuration(md, "observePeriod") return nil } diff --git a/handler/http2/handler.go b/handler/http2/handler.go index 97ae18a..b7f94c9 100644 --- a/handler/http2/handler.go +++ b/handler/http2/handler.go @@ -419,7 +419,11 @@ func (h *http2Handler) observeStats(ctx context.Context) { return } - ticker := time.NewTicker(5 * time.Second) + d := h.md.observePeriod + if d < time.Millisecond { + d = 5 * time.Second + } + ticker := time.NewTicker(d) defer ticker.Stop() for { diff --git a/handler/http2/metadata.go b/handler/http2/metadata.go index 9d21b9d..fcd8e9b 100644 --- a/handler/http2/metadata.go +++ b/handler/http2/metadata.go @@ -3,6 +3,7 @@ package http2 import ( "net/http" "strings" + "time" mdata "github.com/go-gost/core/metadata" mdutil "github.com/go-gost/core/metadata/util" @@ -17,19 +18,11 @@ type metadata struct { header http.Header hash string authBasicRealm string + observePeriod time.Duration } func (h *http2Handler) parseMetadata(md mdata.Metadata) error { - const ( - header = "header" - probeResistKey = "probeResistance" - probeResistKeyX = "probe_resist" - knock = "knock" - hash = "hash" - authBasicRealm = "authBasicRealm" - ) - - if m := mdutil.GetStringMapString(md, header); len(m) > 0 { + if m := mdutil.GetStringMapString(md, "http.header", "header"); len(m) > 0 { hd := http.Header{} for k, v := range m { hd.Add(k, v) @@ -37,21 +30,19 @@ func (h *http2Handler) parseMetadata(md mdata.Metadata) error { h.md.header = hd } - pr := mdutil.GetString(md, probeResistKey) - if pr == "" { - pr = mdutil.GetString(md, probeResistKeyX) - } - if pr != "" { + if pr := mdutil.GetString(md, "probeResist", "probe_resist"); pr != "" { if ss := strings.SplitN(pr, ":", 2); len(ss) == 2 { h.md.probeResistance = &probeResistance{ Type: ss[0], Value: ss[1], - Knock: mdutil.GetString(md, knock), + Knock: mdutil.GetString(md, "knock"), } } } - h.md.hash = mdutil.GetString(md, hash) - h.md.authBasicRealm = mdutil.GetString(md, authBasicRealm) + h.md.hash = mdutil.GetString(md, "hash") + h.md.authBasicRealm = mdutil.GetString(md, "authBasicRealm") + + h.md.observePeriod = mdutil.GetDuration(md, "observePeriod") return nil } diff --git a/handler/relay/handler.go b/handler/relay/handler.go index 850cae8..4b368ae 100644 --- a/handler/relay/handler.go +++ b/handler/relay/handler.go @@ -204,7 +204,11 @@ func (h *relayHandler) observeStats(ctx context.Context) { return } - ticker := time.NewTicker(5 * time.Second) + d := h.md.observePeriod + if d < time.Millisecond { + d = 5 * time.Second + } + ticker := time.NewTicker(d) defer ticker.Stop() for { diff --git a/handler/relay/metadata.go b/handler/relay/metadata.go index 06479c0..bc82712 100644 --- a/handler/relay/metadata.go +++ b/handler/relay/metadata.go @@ -16,28 +16,21 @@ type metadata struct { noDelay bool hash string muxCfg *mux.Config + observePeriod time.Duration } func (h *relayHandler) parseMetadata(md mdata.Metadata) (err error) { - const ( - readTimeout = "readTimeout" - enableBind = "bind" - udpBufferSize = "udpBufferSize" - noDelay = "nodelay" - hash = "hash" - ) + h.md.readTimeout = mdutil.GetDuration(md, "readTimeout") + h.md.enableBind = mdutil.GetBool(md, "bind") + h.md.noDelay = mdutil.GetBool(md, "nodelay") - h.md.readTimeout = mdutil.GetDuration(md, readTimeout) - h.md.enableBind = mdutil.GetBool(md, enableBind) - h.md.noDelay = mdutil.GetBool(md, noDelay) - - if bs := mdutil.GetInt(md, udpBufferSize); bs > 0 { + if bs := mdutil.GetInt(md, "udpBufferSize"); bs > 0 { h.md.udpBufferSize = int(math.Min(math.Max(float64(bs), 512), 64*1024)) } else { h.md.udpBufferSize = 4096 } - h.md.hash = mdutil.GetString(md, hash) + h.md.hash = mdutil.GetString(md, "hash") h.md.muxCfg = &mux.Config{ Version: mdutil.GetInt(md, "mux.version"), @@ -49,5 +42,7 @@ func (h *relayHandler) parseMetadata(md mdata.Metadata) (err error) { MaxStreamBuffer: mdutil.GetInt(md, "mux.maxStreamBuffer"), } + h.md.observePeriod = mdutil.GetDuration(md, "observePeriod") + return } diff --git a/handler/socks/v4/handler.go b/handler/socks/v4/handler.go index c0f06ab..53d274c 100644 --- a/handler/socks/v4/handler.go +++ b/handler/socks/v4/handler.go @@ -14,9 +14,9 @@ import ( "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" "github.com/go-gost/x/registry" - stats_util "github.com/go-gost/x/internal/util/stats" "github.com/go-gost/x/stats" stats_wrapper "github.com/go-gost/x/stats/wrapper" ) @@ -218,7 +218,11 @@ func (h *socks4Handler) observeStats(ctx context.Context) { return } - ticker := time.NewTicker(5 * time.Second) + d := h.md.observePeriod + if d < time.Millisecond { + d = 5 * time.Second + } + ticker := time.NewTicker(d) defer ticker.Stop() for { diff --git a/handler/socks/v4/metadata.go b/handler/socks/v4/metadata.go index 21ad759..318221a 100644 --- a/handler/socks/v4/metadata.go +++ b/handler/socks/v4/metadata.go @@ -8,17 +8,14 @@ import ( ) type metadata struct { - readTimeout time.Duration - hash string + readTimeout time.Duration + hash string + observePeriod time.Duration } func (h *socks4Handler) parseMetadata(md mdata.Metadata) (err error) { - const ( - readTimeout = "readTimeout" - hash = "hash" - ) - - h.md.readTimeout = mdutil.GetDuration(md, readTimeout) - h.md.hash = mdutil.GetString(md, hash) + h.md.readTimeout = mdutil.GetDuration(md, "readTimeout") + h.md.hash = mdutil.GetString(md, "hash") + h.md.observePeriod = mdutil.GetDuration(md, "observePeriod") return } diff --git a/handler/socks/v5/handler.go b/handler/socks/v5/handler.go index 034b29e..3d14482 100644 --- a/handler/socks/v5/handler.go +++ b/handler/socks/v5/handler.go @@ -160,7 +160,11 @@ func (h *socks5Handler) observeStats(ctx context.Context) { return } - ticker := time.NewTicker(5 * time.Second) + d := h.md.observePeriod + if d < time.Millisecond { + d = 5 * time.Second + } + ticker := time.NewTicker(d) defer ticker.Stop() for { diff --git a/handler/socks/v5/metadata.go b/handler/socks/v5/metadata.go index ec31575..0b23c0d 100644 --- a/handler/socks/v5/metadata.go +++ b/handler/socks/v5/metadata.go @@ -18,32 +18,23 @@ type metadata struct { compatibilityMode bool hash string muxCfg *mux.Config + observePeriod time.Duration } func (h *socks5Handler) parseMetadata(md mdata.Metadata) (err error) { - const ( - readTimeout = "readTimeout" - noTLS = "notls" - enableBind = "bind" - enableUDP = "udp" - udpBufferSize = "udpBufferSize" - compatibilityMode = "comp" - hash = "hash" - ) + h.md.readTimeout = mdutil.GetDuration(md, "readTimeout") + h.md.noTLS = mdutil.GetBool(md, "notls") + h.md.enableBind = mdutil.GetBool(md, "bind") + h.md.enableUDP = mdutil.GetBool(md, "udp") - h.md.readTimeout = mdutil.GetDuration(md, readTimeout) - h.md.noTLS = mdutil.GetBool(md, noTLS) - h.md.enableBind = mdutil.GetBool(md, enableBind) - h.md.enableUDP = mdutil.GetBool(md, enableUDP) - - if bs := mdutil.GetInt(md, udpBufferSize); bs > 0 { + if bs := mdutil.GetInt(md, "udpBufferSize"); bs > 0 { h.md.udpBufferSize = int(math.Min(math.Max(float64(bs), 512), 64*1024)) } else { h.md.udpBufferSize = 4096 } - h.md.compatibilityMode = mdutil.GetBool(md, compatibilityMode) - h.md.hash = mdutil.GetString(md, hash) + h.md.compatibilityMode = mdutil.GetBool(md, "comp") + h.md.hash = mdutil.GetString(md, "hash") h.md.muxCfg = &mux.Config{ Version: mdutil.GetInt(md, "mux.version"), @@ -55,5 +46,7 @@ func (h *socks5Handler) parseMetadata(md mdata.Metadata) (err error) { MaxStreamBuffer: mdutil.GetInt(md, "mux.maxStreamBuffer"), } + h.md.observePeriod = mdutil.GetDuration(md, "observePeriod") + return nil } diff --git a/service/service.go b/service/service.go index 1085de3..d7ccd44 100644 --- a/service/service.go +++ b/service/service.go @@ -24,15 +24,16 @@ import ( ) type options struct { - admission admission.Admission - recorders []recorder.RecorderObject - preUp []string - postUp []string - preDown []string - postDown []string - stats *stats.Stats - observer observer.Observer - logger logger.Logger + admission admission.Admission + recorders []recorder.RecorderObject + preUp []string + postUp []string + preDown []string + postDown []string + stats *stats.Stats + observer observer.Observer + observePeriod time.Duration + logger logger.Logger } type Option func(opts *options) @@ -85,6 +86,12 @@ func ObserverOption(observer observer.Observer) Option { } } +func ObservePeriodOption(period time.Duration) Option { + return func(opts *options) { + opts.observePeriod = period + } +} + func LoggerOption(logger logger.Logger) Option { return func(opts *options) { opts.logger = logger @@ -294,7 +301,12 @@ func (s *defaultService) observeStats(ctx context.Context) { return } - ticker := time.NewTicker(5 * time.Second) + d := s.options.observePeriod + if d < time.Millisecond { + d = 5 * time.Second + } + + ticker := time.NewTicker(d) defer ticker.Stop() for {