diff --git a/admission/admission.go b/admission/admission.go index 2723594b..dda09b8f 100644 --- a/admission/admission.go +++ b/admission/admission.go @@ -13,6 +13,7 @@ import ( "github.com/go-gost/core/logger" "github.com/go-gost/x/internal/loader" "github.com/go-gost/x/internal/matcher" + xlogger "github.com/go-gost/x/logger" ) type options struct { @@ -75,6 +76,7 @@ type localAdmission struct { mu sync.RWMutex cancelFunc context.CancelFunc options options + logger logger.Logger } // NewAdmission creates and initializes a new Admission using matcher patterns as its match rules. @@ -85,18 +87,17 @@ func NewAdmission(opts ...Option) admission.Admission { opt(&options) } - ctx, cancel := context.WithCancel(context.TODO()) + ctx, cancel := context.WithCancel(context.Background()) p := &localAdmission{ cancelFunc: cancel, options: options, + logger: options.logger, + } + if p.logger == nil { + p.logger = xlogger.Nop() } - if err := p.reload(ctx); err != nil { - options.logger.Warnf("reload: %v", err) - } - if p.options.period > 0 { - go p.periodReload(ctx) - } + go p.periodReload(ctx) return p } @@ -117,13 +118,20 @@ func (p *localAdmission) Admit(ctx context.Context, addr string, opts ...admissi p.options.whitelist && matched if !b { - p.options.logger.Debugf("%s is denied", addr) + p.logger.Debugf("%s is denied", addr) } return b } func (p *localAdmission) periodReload(ctx context.Context) error { + if err := p.reload(ctx); err != nil { + p.logger.Warnf("reload: %v", err) + } + period := p.options.period + if period <= 0 { + return nil + } if period < time.Second { period = time.Second } @@ -134,7 +142,7 @@ func (p *localAdmission) periodReload(ctx context.Context) error { select { case <-ticker.C: if err := p.reload(ctx); err != nil { - p.options.logger.Warnf("reload: %v", err) + p.logger.Warnf("reload: %v", err) // return err } case <-ctx.Done(): @@ -162,7 +170,7 @@ func (p *localAdmission) reload(ctx context.Context) error { continue } if ipAddr, _ := net.ResolveIPAddr("ip", pattern); ipAddr != nil { - p.options.logger.Debugf("resolve IP: %s -> %s", pattern, ipAddr) + p.logger.Debugf("resolve IP: %s -> %s", pattern, ipAddr) ips = append(ips, ipAddr.IP) } } @@ -181,7 +189,7 @@ func (p *localAdmission) load(ctx context.Context) (patterns []string, err error if lister, ok := p.options.fileLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - p.options.logger.Warnf("file loader: %v", er) + p.logger.Warnf("file loader: %v", er) } for _, s := range list { if line := p.parseLine(s); line != "" { @@ -191,7 +199,7 @@ func (p *localAdmission) load(ctx context.Context) (patterns []string, err error } else { r, er := p.options.fileLoader.Load(ctx) if er != nil { - p.options.logger.Warnf("file loader: %v", er) + p.logger.Warnf("file loader: %v", er) } if v, _ := p.parsePatterns(r); v != nil { patterns = append(patterns, v...) @@ -202,13 +210,13 @@ func (p *localAdmission) load(ctx context.Context) (patterns []string, err error if lister, ok := p.options.redisLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - p.options.logger.Warnf("redis loader: %v", er) + p.logger.Warnf("redis loader: %v", er) } patterns = append(patterns, list...) } else { r, er := p.options.redisLoader.Load(ctx) if er != nil { - p.options.logger.Warnf("redis loader: %v", er) + p.logger.Warnf("redis loader: %v", er) } if v, _ := p.parsePatterns(r); v != nil { patterns = append(patterns, v...) @@ -219,14 +227,14 @@ func (p *localAdmission) load(ctx context.Context) (patterns []string, err error if p.options.httpLoader != nil { r, er := p.options.httpLoader.Load(ctx) if er != nil { - p.options.logger.Warnf("http loader: %v", er) + p.logger.Warnf("http loader: %v", er) } if v, _ := p.parsePatterns(r); v != nil { patterns = append(patterns, v...) } } - p.options.logger.Debugf("load items %d", len(patterns)) + p.logger.Debugf("load items %d", len(patterns)) return } diff --git a/auth/auth.go b/auth/auth.go index ef35f03c..88d7fe68 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -67,6 +67,7 @@ type authenticator struct { mu sync.RWMutex cancelFunc context.CancelFunc options options + logger logger.Logger } // NewAuthenticator creates an Authenticator that authenticates client by pre-defined user mapping. @@ -75,23 +76,19 @@ func NewAuthenticator(opts ...Option) auth.Authenticator { for _, opt := range opts { opt(&options) } - if options.logger == nil { - options.logger = xlogger.Nop() - } - ctx, cancel := context.WithCancel(context.TODO()) + ctx, cancel := context.WithCancel(context.Background()) p := &authenticator{ kvs: make(map[string]string), cancelFunc: cancel, options: options, + logger: options.logger, + } + if p.logger == nil { + p.logger = xlogger.Nop() } - if err := p.reload(ctx); err != nil { - options.logger.Warnf("reload: %v", err) - } - if p.options.period > 0 { - go p.periodReload(ctx) - } + go p.periodReload(ctx) return p } @@ -114,7 +111,14 @@ func (p *authenticator) Authenticate(ctx context.Context, user, password string, } func (p *authenticator) periodReload(ctx context.Context) error { + if err := p.reload(ctx); err != nil { + p.logger.Warnf("reload: %v", err) + } + period := p.options.period + if period <= 0 { + return nil + } if period < time.Second { period = time.Second } @@ -125,7 +129,7 @@ func (p *authenticator) periodReload(ctx context.Context) error { select { case <-ticker.C: if err := p.reload(ctx); err != nil { - p.options.logger.Warnf("reload: %v", err) + p.logger.Warnf("reload: %v", err) // return err } case <-ctx.Done(): @@ -145,7 +149,7 @@ func (p *authenticator) reload(ctx context.Context) (err error) { kvs[k] = v } - p.options.logger.Debugf("load items %d", len(m)) + p.logger.Debugf("load items %d", len(m)) p.mu.Lock() defer p.mu.Unlock() @@ -162,13 +166,13 @@ func (p *authenticator) load(ctx context.Context) (m map[string]string, err erro if mapper, ok := p.options.fileLoader.(loader.Mapper); ok { auths, er := mapper.Map(ctx) if er != nil { - p.options.logger.Warnf("file loader: %v", er) + p.logger.Warnf("file loader: %v", er) } m = auths } else { r, er := p.options.fileLoader.Load(ctx) if er != nil { - p.options.logger.Warnf("file loader: %v", er) + p.logger.Warnf("file loader: %v", er) } if auths, _ := p.parseAuths(r); auths != nil { m = auths @@ -179,7 +183,7 @@ func (p *authenticator) load(ctx context.Context) (m map[string]string, err erro if mapper, ok := p.options.fileLoader.(loader.Mapper); ok { auths, er := mapper.Map(ctx) if er != nil { - p.options.logger.Warnf("file loader: %v", er) + p.logger.Warnf("file loader: %v", er) } for k, v := range auths { m[k] = v @@ -187,7 +191,7 @@ func (p *authenticator) load(ctx context.Context) (m map[string]string, err erro } else { r, er := p.options.redisLoader.Load(ctx) if er != nil { - p.options.logger.Warnf("redis loader: %v", er) + p.logger.Warnf("redis loader: %v", er) } if auths, _ := p.parseAuths(r); auths != nil { for k, v := range auths { @@ -199,7 +203,7 @@ func (p *authenticator) load(ctx context.Context) (m map[string]string, err erro if p.options.httpLoader != nil { r, er := p.options.httpLoader.Load(ctx) if er != nil { - p.options.logger.Warnf("http loader: %v", er) + p.logger.Warnf("http loader: %v", er) } if auths, _ := p.parseAuths(r); auths != nil { for k, v := range auths { diff --git a/bypass/bypass.go b/bypass/bypass.go index 62835cec..93ad176f 100644 --- a/bypass/bypass.go +++ b/bypass/bypass.go @@ -17,6 +17,7 @@ import ( "github.com/go-gost/x/internal/loader" "github.com/go-gost/x/internal/matcher" xnet "github.com/go-gost/x/internal/net" + xlogger "github.com/go-gost/x/logger" ) var ( @@ -82,9 +83,10 @@ type localBypass struct { addrMatcher matcher.Matcher wildcardMatcher matcher.Matcher ipRangeMatcher matcher.Matcher - cancelFunc context.CancelFunc options options + logger logger.Logger mu sync.RWMutex + cancelFunc context.CancelFunc } // NewBypass creates and initializes a new Bypass. @@ -95,36 +97,43 @@ func NewBypass(opts ...Option) bypass.Bypass { opt(&options) } - ctx, cancel := context.WithCancel(context.TODO()) + ctx, cancel := context.WithCancel(context.Background()) - bp := &localBypass{ + p := &localBypass{ cancelFunc: cancel, options: options, + logger: options.logger, + } + if p.logger == nil { + p.logger = xlogger.Nop() } - if err := bp.reload(ctx); err != nil { - options.logger.Warnf("reload: %v", err) - } - if bp.options.period > 0 { - go bp.periodReload(ctx) - } + go p.periodReload(ctx) - return bp + return p } -func (bp *localBypass) periodReload(ctx context.Context) error { - period := bp.options.period +func (p *localBypass) periodReload(ctx context.Context) error { + if err := p.reload(ctx); err != nil { + p.logger.Warnf("reload: %v", err) + } + + period := p.options.period + if period <= 0 { + return nil + } if period < time.Second { period = time.Second } + ticker := time.NewTicker(period) defer ticker.Stop() for { select { case <-ticker.C: - if err := bp.reload(ctx); err != nil { - bp.options.logger.Warnf("reload: %v", err) + if err := p.reload(ctx); err != nil { + p.logger.Warnf("reload: %v", err) // return err } case <-ctx.Done(): @@ -133,13 +142,13 @@ func (bp *localBypass) periodReload(ctx context.Context) error { } } -func (bp *localBypass) reload(ctx context.Context) error { - v, err := bp.load(ctx) +func (p *localBypass) reload(ctx context.Context) error { + v, err := p.load(ctx) if err != nil { return err } - patterns := append(bp.options.matchers, v...) - bp.options.logger.Debugf("load items %d", len(patterns)) + patterns := append(p.options.matchers, v...) + p.logger.Debugf("load items %d", len(patterns)) var addrs []string var inets []*net.IPNet @@ -165,62 +174,62 @@ func (bp *localBypass) reload(ctx context.Context) error { addrs = append(addrs, pattern) } - bp.mu.Lock() - defer bp.mu.Unlock() + p.mu.Lock() + defer p.mu.Unlock() - bp.cidrMatcher = matcher.CIDRMatcher(inets) - bp.addrMatcher = matcher.AddrMatcher(addrs) - bp.wildcardMatcher = matcher.WildcardMatcher(wildcards) - bp.ipRangeMatcher = matcher.IPRangeMatcher(ipRanges) + p.cidrMatcher = matcher.CIDRMatcher(inets) + p.addrMatcher = matcher.AddrMatcher(addrs) + p.wildcardMatcher = matcher.WildcardMatcher(wildcards) + p.ipRangeMatcher = matcher.IPRangeMatcher(ipRanges) return nil } -func (bp *localBypass) load(ctx context.Context) (patterns []string, err error) { - if bp.options.fileLoader != nil { - if lister, ok := bp.options.fileLoader.(loader.Lister); ok { +func (p *localBypass) load(ctx context.Context) (patterns []string, err error) { + if p.options.fileLoader != nil { + if lister, ok := p.options.fileLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - bp.options.logger.Warnf("file loader: %v", er) + p.logger.Warnf("file loader: %v", er) } for _, s := range list { - if line := bp.parseLine(s); line != "" { + if line := p.parseLine(s); line != "" { patterns = append(patterns, line) } } } else { - r, er := bp.options.fileLoader.Load(ctx) + r, er := p.options.fileLoader.Load(ctx) if er != nil { - bp.options.logger.Warnf("file loader: %v", er) + p.logger.Warnf("file loader: %v", er) } - if v, _ := bp.parsePatterns(r); v != nil { + if v, _ := p.parsePatterns(r); v != nil { patterns = append(patterns, v...) } } } - if bp.options.redisLoader != nil { - if lister, ok := bp.options.redisLoader.(loader.Lister); ok { + if p.options.redisLoader != nil { + if lister, ok := p.options.redisLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - bp.options.logger.Warnf("redis loader: %v", er) + p.logger.Warnf("redis loader: %v", er) } patterns = append(patterns, list...) } else { - r, er := bp.options.redisLoader.Load(ctx) + r, er := p.options.redisLoader.Load(ctx) if er != nil { - bp.options.logger.Warnf("redis loader: %v", er) + p.logger.Warnf("redis loader: %v", er) } - if v, _ := bp.parsePatterns(r); v != nil { + if v, _ := p.parsePatterns(r); v != nil { patterns = append(patterns, v...) } } } - if bp.options.httpLoader != nil { - r, er := bp.options.httpLoader.Load(ctx) + if p.options.httpLoader != nil { + r, er := p.options.httpLoader.Load(ctx) if er != nil { - bp.options.logger.Warnf("http loader: %v", er) + p.logger.Warnf("http loader: %v", er) } - if v, _ := bp.parsePatterns(r); v != nil { + if v, _ := p.parsePatterns(r); v != nil { patterns = append(patterns, v...) } } @@ -228,14 +237,14 @@ func (bp *localBypass) load(ctx context.Context) (patterns []string, err error) return } -func (bp *localBypass) parsePatterns(r io.Reader) (patterns []string, err error) { +func (p *localBypass) parsePatterns(r io.Reader) (patterns []string, err error) { if r == nil { return } scanner := bufio.NewScanner(r) for scanner.Scan() { - if line := bp.parseLine(scanner.Text()); line != "" { + if line := p.parseLine(scanner.Text()); line != "" { patterns = append(patterns, line) } } @@ -244,24 +253,24 @@ func (bp *localBypass) parsePatterns(r io.Reader) (patterns []string, err error) return } -func (bp *localBypass) Contains(ctx context.Context, network, addr string, opts ...bypass.Option) bool { - if addr == "" || bp == nil { +func (p *localBypass) Contains(ctx context.Context, network, addr string, opts ...bypass.Option) bool { + if addr == "" || p == nil { return false } - matched := bp.matched(addr) + matched := p.matched(addr) - b := !bp.options.whitelist && matched || - bp.options.whitelist && !matched + b := !p.options.whitelist && matched || + p.options.whitelist && !matched - log := bp.options.logger.WithFields(map[string]any{ + log := p.logger.WithFields(map[string]any{ "sid": ctxvalue.SidFromContext(ctx), }) if b { - log.Debugf("bypass: %s, whitelist: %t", addr, bp.options.whitelist) + log.Debugf("bypass: %s, whitelist: %t", addr, p.options.whitelist) } else { - log.Debugf("pass: %s, whitelist: %t", addr, bp.options.whitelist) + log.Debugf("pass: %s, whitelist: %t", addr, p.options.whitelist) } return b } @@ -270,22 +279,22 @@ func (p *localBypass) IsWhitelist() bool { return p.options.whitelist } -func (bp *localBypass) parseLine(s string) string { +func (p *localBypass) parseLine(s string) string { if n := strings.IndexByte(s, '#'); n >= 0 { s = s[:n] } return strings.TrimSpace(s) } -func (bp *localBypass) matched(addr string) bool { - bp.mu.RLock() - defer bp.mu.RUnlock() +func (p *localBypass) matched(addr string) bool { + p.mu.RLock() + defer p.mu.RUnlock() - if bp.ipRangeMatcher.Match(addr) { + if p.ipRangeMatcher.Match(addr) { return true } - if bp.addrMatcher.Match(addr) { + if p.addrMatcher.Match(addr) { return true } @@ -294,20 +303,20 @@ func (bp *localBypass) matched(addr string) bool { host = addr } - if ip := net.ParseIP(host); ip != nil && bp.cidrMatcher.Match(host) { + if ip := net.ParseIP(host); ip != nil && p.cidrMatcher.Match(host) { return true } - return bp.wildcardMatcher.Match(addr) + return p.wildcardMatcher.Match(addr) } -func (bp *localBypass) Close() error { - bp.cancelFunc() - if bp.options.fileLoader != nil { - bp.options.fileLoader.Close() +func (p *localBypass) Close() error { + p.cancelFunc() + if p.options.fileLoader != nil { + p.options.fileLoader.Close() } - if bp.options.redisLoader != nil { - bp.options.redisLoader.Close() + if p.options.redisLoader != nil { + p.options.redisLoader.Close() } return nil } diff --git a/hop/hop.go b/hop/hop.go index a7cc4817..f94c8a34 100644 --- a/hop/hop.go +++ b/hop/hop.go @@ -19,6 +19,7 @@ import ( "github.com/go-gost/x/config" node_parser "github.com/go-gost/x/config/parsing/node" "github.com/go-gost/x/internal/loader" + xlogger "github.com/go-gost/x/logger" ) type options struct { @@ -89,9 +90,10 @@ func LoggerOption(logger logger.Logger) Option { type chainHop struct { nodes []*chain.Node + options options + logger logger.Logger mu sync.RWMutex cancelFunc context.CancelFunc - options options } func NewHop(opts ...Option) hop.Hop { @@ -106,15 +108,15 @@ func NewHop(opts ...Option) hop.Hop { p := &chainHop{ cancelFunc: cancel, options: options, + logger: options.logger, } - if err := p.reload(ctx); err != nil { - options.logger.Warnf("reload: %v", err) - } - if p.options.period > 0 { - go p.periodReload(ctx) + if p.logger == nil { + p.logger = xlogger.Nop() } + go p.periodReload(ctx) + return p } @@ -133,7 +135,7 @@ func (p *chainHop) Select(ctx context.Context, opts ...hop.SelectOption) *chain. opt(&options) } - log := p.options.logger + log := p.logger // hop level bypass if p.options.bypass != nil && @@ -258,10 +260,18 @@ func (p *chainHop) checkPath(path string, node *chain.Node) bool { } func (p *chainHop) periodReload(ctx context.Context) error { + if err := p.reload(ctx); err != nil { + p.logger.Warnf("reload: %v", err) + } + period := p.options.period + if period <= 0 { + return nil + } if period < time.Second { period = time.Second } + ticker := time.NewTicker(period) defer ticker.Stop() @@ -269,10 +279,10 @@ func (p *chainHop) periodReload(ctx context.Context) error { select { case <-ticker.C: if err := p.reload(ctx); err != nil { - p.options.logger.Warnf("reload: %v", err) + p.logger.Warnf("reload: %v", err) // return err } - p.options.logger.Debug("hop reload done") + p.logger.Debug("hop reload done") case <-ctx.Done(): return ctx.Err() } @@ -286,7 +296,7 @@ func (p *chainHop) reload(ctx context.Context) (err error) { nodes = append(nodes, nl...) - p.options.logger.Debugf("load items %d", len(nodes)) + p.logger.Debugf("load items %d", len(nodes)) p.mu.Lock() defer p.mu.Unlock() @@ -300,7 +310,7 @@ func (p *chainHop) load(ctx context.Context) (nodes []*chain.Node, err error) { if loader := p.options.fileLoader; loader != nil { r, er := loader.Load(ctx) if er != nil { - p.options.logger.Warnf("file loader: %v", er) + p.logger.Warnf("file loader: %v", er) } nodes, _ = p.parseNode(r) } @@ -308,7 +318,7 @@ func (p *chainHop) load(ctx context.Context) (nodes []*chain.Node, err error) { if loader := p.options.redisLoader; loader != nil { r, er := loader.Load(ctx) if er != nil { - p.options.logger.Warnf("redis loader: %v", er) + p.logger.Warnf("redis loader: %v", er) } ns, _ := p.parseNode(r) nodes = append(nodes, ns...) @@ -317,7 +327,7 @@ func (p *chainHop) load(ctx context.Context) (nodes []*chain.Node, err error) { if loader := p.options.httpLoader; loader != nil { r, er := loader.Load(ctx) if er != nil { - p.options.logger.Warnf("http loader: %v", er) + p.logger.Warnf("http loader: %v", er) } if ns, _ := p.parseNode(r); ns != nil { nodes = append(nodes, ns...) diff --git a/hosts/hosts.go b/hosts/hosts.go index a7093f45..3f9eee28 100644 --- a/hosts/hosts.go +++ b/hosts/hosts.go @@ -12,6 +12,7 @@ import ( "github.com/go-gost/core/hosts" "github.com/go-gost/core/logger" "github.com/go-gost/x/internal/loader" + xlogger "github.com/go-gost/x/logger" ) type Mapping struct { @@ -73,9 +74,10 @@ func LoggerOption(logger logger.Logger) Option { // Text from a "#" character until the end of the line is a comment, and is ignored. type hostMapper struct { mappings map[string][]net.IP + options options + logger logger.Logger mu sync.RWMutex cancelFunc context.CancelFunc - options options } func NewHostMapper(opts ...Option) hosts.HostMapper { @@ -89,14 +91,13 @@ func NewHostMapper(opts ...Option) hosts.HostMapper { mappings: make(map[string][]net.IP), cancelFunc: cancel, options: options, + logger: options.logger, + } + if p.logger == nil { + p.logger = xlogger.Nop() } - if err := p.reload(ctx); err != nil { - options.logger.Warnf("reload: %v", err) - } - if p.options.period > 0 { - go p.periodReload(ctx) - } + go p.periodReload(ctx) return p } @@ -167,10 +168,18 @@ func (h *hostMapper) lookup(host string) []net.IP { } func (h *hostMapper) periodReload(ctx context.Context) error { + if err := h.reload(ctx); err != nil { + h.logger.Warnf("reload: %v", err) + } + period := h.options.period + if period <= 0 { + return nil + } if period < time.Second { period = time.Second } + ticker := time.NewTicker(period) defer ticker.Stop() @@ -178,10 +187,10 @@ func (h *hostMapper) periodReload(ctx context.Context) error { select { case <-ticker.C: if err := h.reload(ctx); err != nil { - h.options.logger.Warnf("reload: %v", err) + h.logger.Warnf("reload: %v", err) // return err } - h.options.logger.Debug("hosts reload done") + h.logger.Debug("hosts reload done") case <-ctx.Done(): return ctx.Err() } @@ -215,7 +224,7 @@ func (h *hostMapper) reload(ctx context.Context) (err error) { mapf(m[i].Hostname, m[i].IP) } - h.options.logger.Debugf("load items %d", len(mappings)) + h.logger.Debugf("load items %d", len(mappings)) h.mu.Lock() defer h.mu.Unlock() @@ -230,7 +239,7 @@ func (h *hostMapper) load(ctx context.Context) (mappings []Mapping, err error) { if lister, ok := h.options.fileLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - h.options.logger.Warnf("file loader: %v", er) + h.logger.Warnf("file loader: %v", er) } for _, s := range list { mappings = append(mappings, h.parseLine(s)...) @@ -238,7 +247,7 @@ func (h *hostMapper) load(ctx context.Context) (mappings []Mapping, err error) { } else { r, er := h.options.fileLoader.Load(ctx) if er != nil { - h.options.logger.Warnf("file loader: %v", er) + h.logger.Warnf("file loader: %v", er) } mappings, _ = h.parseMapping(r) } @@ -248,7 +257,7 @@ func (h *hostMapper) load(ctx context.Context) (mappings []Mapping, err error) { if lister, ok := h.options.redisLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - h.options.logger.Warnf("redis loader: %v", er) + h.logger.Warnf("redis loader: %v", er) } for _, s := range list { mappings = append(mappings, h.parseLine(s)...) @@ -256,7 +265,7 @@ func (h *hostMapper) load(ctx context.Context) (mappings []Mapping, err error) { } else { r, er := h.options.redisLoader.Load(ctx) if er != nil { - h.options.logger.Warnf("redis loader: %v", er) + h.logger.Warnf("redis loader: %v", er) } if m, _ := h.parseMapping(r); m != nil { mappings = append(mappings, m...) @@ -266,7 +275,7 @@ func (h *hostMapper) load(ctx context.Context) (mappings []Mapping, err error) { if h.options.httpLoader != nil { r, er := h.options.httpLoader.Load(ctx) if er != nil { - h.options.logger.Warnf("http loader: %v", er) + h.logger.Warnf("http loader: %v", er) } if m, _ := h.parseMapping(r); m != nil { mappings = append(mappings, m...) diff --git a/ingress/ingress.go b/ingress/ingress.go index e6487afb..e40be772 100644 --- a/ingress/ingress.go +++ b/ingress/ingress.go @@ -12,6 +12,7 @@ import ( "github.com/go-gost/core/ingress" "github.com/go-gost/core/logger" "github.com/go-gost/x/internal/loader" + xlogger "github.com/go-gost/x/logger" ) type options struct { @@ -63,9 +64,10 @@ func LoggerOption(logger logger.Logger) Option { type localIngress struct { rules map[string]*ingress.Rule - cancelFunc context.CancelFunc options options + logger logger.Logger mu sync.RWMutex + cancelFunc context.CancelFunc } // NewIngress creates and initializes a new Ingress. @@ -80,23 +82,30 @@ func NewIngress(opts ...Option) ingress.Ingress { ing := &localIngress{ cancelFunc: cancel, options: options, + logger: options.logger, + } + if ing.logger == nil { + ing.logger = xlogger.Nop() } - if err := ing.reload(ctx); err != nil { - options.logger.Warnf("reload: %v", err) - } - if ing.options.period > 0 { - go ing.periodReload(ctx) - } + go ing.periodReload(ctx) return ing } func (ing *localIngress) periodReload(ctx context.Context) error { + if err := ing.reload(ctx); err != nil { + ing.logger.Warnf("reload: %v", err) + } + period := ing.options.period + if period <= 0 { + return nil + } if period < time.Second { period = time.Second } + ticker := time.NewTicker(period) defer ticker.Stop() @@ -104,7 +113,7 @@ func (ing *localIngress) periodReload(ctx context.Context) error { select { case <-ticker.C: if err := ing.reload(ctx); err != nil { - ing.options.logger.Warnf("reload: %v", err) + ing.logger.Warnf("reload: %v", err) // return err } case <-ctx.Done(): @@ -139,7 +148,7 @@ func (ing *localIngress) reload(ctx context.Context) error { fn(rule) } - ing.options.logger.Debugf("load items %d", len(rules)) + ing.logger.Debugf("load items %d", len(rules)) ing.mu.Lock() defer ing.mu.Unlock() @@ -154,7 +163,7 @@ func (ing *localIngress) load(ctx context.Context) (rules []*ingress.Rule, err e if lister, ok := ing.options.fileLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - ing.options.logger.Warnf("file loader: %v", er) + ing.logger.Warnf("file loader: %v", er) } for _, s := range list { rules = append(rules, ing.parseLine(s)) @@ -162,7 +171,7 @@ func (ing *localIngress) load(ctx context.Context) (rules []*ingress.Rule, err e } else { r, er := ing.options.fileLoader.Load(ctx) if er != nil { - ing.options.logger.Warnf("file loader: %v", er) + ing.logger.Warnf("file loader: %v", er) } if v, _ := ing.parseRules(r); v != nil { rules = append(rules, v...) @@ -173,7 +182,7 @@ func (ing *localIngress) load(ctx context.Context) (rules []*ingress.Rule, err e if lister, ok := ing.options.redisLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - ing.options.logger.Warnf("redis loader: %v", er) + ing.logger.Warnf("redis loader: %v", er) } for _, v := range list { rules = append(rules, ing.parseLine(v)) @@ -181,7 +190,7 @@ func (ing *localIngress) load(ctx context.Context) (rules []*ingress.Rule, err e } else { r, er := ing.options.redisLoader.Load(ctx) if er != nil { - ing.options.logger.Warnf("redis loader: %v", er) + ing.logger.Warnf("redis loader: %v", er) } v, _ := ing.parseRules(r) rules = append(rules, v...) @@ -190,7 +199,7 @@ func (ing *localIngress) load(ctx context.Context) (rules []*ingress.Rule, err e if ing.options.httpLoader != nil { r, er := ing.options.httpLoader.Load(ctx) if er != nil { - ing.options.logger.Warnf("http loader: %v", er) + ing.logger.Warnf("http loader: %v", er) } v, _ := ing.parseRules(r) rules = append(rules, v...) @@ -225,7 +234,7 @@ func (ing *localIngress) GetRule(ctx context.Context, host string, opts ...ingre host = v } - ing.options.logger.Debugf("ingress: lookup %s", host) + ing.logger.Debugf("ingress: lookup %s", host) ep := ing.lookup(host) if ep == nil { ep = ing.lookup("." + host) @@ -245,7 +254,7 @@ func (ing *localIngress) GetRule(ctx context.Context, host string, opts ...ingre } if ep != nil { - ing.options.logger.Debugf("ingress: %s -> %s:%s", host, ep.Hostname, ep.Endpoint) + ing.logger.Debugf("ingress: %s -> %s:%s", host, ep.Hostname, ep.Endpoint) } return ep diff --git a/limiter/conn/conn.go b/limiter/conn/conn.go index 2ec51070..a61d0dc8 100644 --- a/limiter/conn/conn.go +++ b/limiter/conn/conn.go @@ -13,6 +13,7 @@ import ( limiter "github.com/go-gost/core/limiter/conn" "github.com/go-gost/core/logger" "github.com/go-gost/x/internal/loader" + xlogger "github.com/go-gost/x/logger" "github.com/yl2chen/cidranger" ) @@ -75,6 +76,7 @@ type connLimiter struct { mu sync.Mutex cancelFunc context.CancelFunc options options + logger logger.Logger } func NewConnLimiter(opts ...Option) limiter.ConnLimiter { @@ -90,14 +92,14 @@ func NewConnLimiter(opts ...Option) limiter.ConnLimiter { limits: make(map[string]limiter.Limiter), options: options, cancelFunc: cancel, + logger: options.logger, + } + if lim.logger == nil { + lim.logger = xlogger.Nop() } - if err := lim.reload(ctx); err != nil { - options.logger.Warnf("reload: %v", err) - } - if lim.options.period > 0 { - go lim.periodReload(ctx) - } + go lim.periodReload(ctx) + return lim } @@ -150,18 +152,26 @@ func (l *connLimiter) Limiter(key string) limiter.Limiter { } l.limits[key] = lim - if lim != nil && l.options.logger != nil { - l.options.logger.Debugf("conn limit for %s: %d", key, lim.Limit()) + if lim != nil && l.logger != nil { + l.logger.Debugf("conn limit for %s: %d", key, lim.Limit()) } return lim } func (l *connLimiter) periodReload(ctx context.Context) error { + if err := l.reload(ctx); err != nil { + l.logger.Warnf("reload: %v", err) + } + period := l.options.period + if period <= 0 { + return nil + } if period < time.Second { period = time.Second } + ticker := time.NewTicker(period) defer ticker.Stop() @@ -169,7 +179,7 @@ func (l *connLimiter) periodReload(ctx context.Context) error { select { case <-ticker.C: if err := l.reload(ctx); err != nil { - l.options.logger.Warnf("reload: %v", err) + l.logger.Warnf("reload: %v", err) // return err } case <-ctx.Done(): @@ -228,7 +238,7 @@ func (l *connLimiter) load(ctx context.Context) (patterns []string, err error) { if lister, ok := l.options.fileLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - l.options.logger.Warnf("file loader: %v", er) + l.logger.Warnf("file loader: %v", er) } for _, s := range list { if line := l.parseLine(s); line != "" { @@ -238,7 +248,7 @@ func (l *connLimiter) load(ctx context.Context) (patterns []string, err error) { } else { r, er := l.options.fileLoader.Load(ctx) if er != nil { - l.options.logger.Warnf("file loader: %v", er) + l.logger.Warnf("file loader: %v", er) } if v, _ := l.parsePatterns(r); v != nil { patterns = append(patterns, v...) @@ -249,13 +259,13 @@ func (l *connLimiter) load(ctx context.Context) (patterns []string, err error) { if lister, ok := l.options.redisLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - l.options.logger.Warnf("redis loader: %v", er) + l.logger.Warnf("redis loader: %v", er) } patterns = append(patterns, list...) } else { r, er := l.options.redisLoader.Load(ctx) if er != nil { - l.options.logger.Warnf("redis loader: %v", er) + l.logger.Warnf("redis loader: %v", er) } if v, _ := l.parsePatterns(r); v != nil { patterns = append(patterns, v...) @@ -265,14 +275,14 @@ func (l *connLimiter) load(ctx context.Context) (patterns []string, err error) { if l.options.httpLoader != nil { r, er := l.options.httpLoader.Load(ctx) if er != nil { - l.options.logger.Warnf("http loader: %v", er) + l.logger.Warnf("http loader: %v", er) } if v, _ := l.parsePatterns(r); v != nil { patterns = append(patterns, v...) } } - l.options.logger.Debugf("load items %d", len(patterns)) + l.logger.Debugf("load items %d", len(patterns)) return } diff --git a/limiter/rate/rate.go b/limiter/rate/rate.go index 34616158..b7f91551 100644 --- a/limiter/rate/rate.go +++ b/limiter/rate/rate.go @@ -13,6 +13,7 @@ import ( limiter "github.com/go-gost/core/limiter/rate" "github.com/go-gost/core/logger" "github.com/go-gost/x/internal/loader" + xlogger "github.com/go-gost/x/logger" "github.com/yl2chen/cidranger" ) @@ -75,6 +76,7 @@ type rateLimiter struct { mu sync.Mutex cancelFunc context.CancelFunc options options + logger logger.Logger } func NewRateLimiter(opts ...Option) limiter.RateLimiter { @@ -90,14 +92,14 @@ func NewRateLimiter(opts ...Option) limiter.RateLimiter { limits: make(map[string]limiter.Limiter), options: options, cancelFunc: cancel, + logger: options.logger, + } + if lim.logger == nil { + lim.logger = xlogger.Nop() } - if err := lim.reload(ctx); err != nil { - options.logger.Warnf("reload: %v", err) - } - if lim.options.period > 0 { - go lim.periodReload(ctx) - } + go lim.periodReload(ctx) + return lim } @@ -150,18 +152,26 @@ func (l *rateLimiter) Limiter(key string) limiter.Limiter { } l.limits[key] = lim - if lim != nil && l.options.logger != nil { - l.options.logger.Debugf("input limit for %s: %d", key, lim.Limit()) + if lim != nil && l.logger != nil { + l.logger.Debugf("input limit for %s: %d", key, lim.Limit()) } return lim } func (l *rateLimiter) periodReload(ctx context.Context) error { + if err := l.reload(ctx); err != nil { + l.logger.Warnf("reload: %v", err) + } + period := l.options.period + if period <= 0 { + return nil + } if period < time.Second { period = time.Second } + ticker := time.NewTicker(period) defer ticker.Stop() @@ -169,7 +179,7 @@ func (l *rateLimiter) periodReload(ctx context.Context) error { select { case <-ticker.C: if err := l.reload(ctx); err != nil { - l.options.logger.Warnf("reload: %v", err) + l.logger.Warnf("reload: %v", err) // return err } case <-ctx.Done(): @@ -228,7 +238,7 @@ func (l *rateLimiter) load(ctx context.Context) (patterns []string, err error) { if lister, ok := l.options.fileLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - l.options.logger.Warnf("file loader: %v", er) + l.logger.Warnf("file loader: %v", er) } for _, s := range list { if line := l.parseLine(s); line != "" { @@ -238,7 +248,7 @@ func (l *rateLimiter) load(ctx context.Context) (patterns []string, err error) { } else { r, er := l.options.fileLoader.Load(ctx) if er != nil { - l.options.logger.Warnf("file loader: %v", er) + l.logger.Warnf("file loader: %v", er) } if v, _ := l.parsePatterns(r); v != nil { patterns = append(patterns, v...) @@ -249,13 +259,13 @@ func (l *rateLimiter) load(ctx context.Context) (patterns []string, err error) { if lister, ok := l.options.redisLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - l.options.logger.Warnf("redis loader: %v", er) + l.logger.Warnf("redis loader: %v", er) } patterns = append(patterns, list...) } else { r, er := l.options.redisLoader.Load(ctx) if er != nil { - l.options.logger.Warnf("redis loader: %v", er) + l.logger.Warnf("redis loader: %v", er) } if v, _ := l.parsePatterns(r); v != nil { patterns = append(patterns, v...) @@ -265,14 +275,14 @@ func (l *rateLimiter) load(ctx context.Context) (patterns []string, err error) { if l.options.httpLoader != nil { r, er := l.options.httpLoader.Load(ctx) if er != nil { - l.options.logger.Warnf("http loader: %v", er) + l.logger.Warnf("http loader: %v", er) } if v, _ := l.parsePatterns(r); v != nil { patterns = append(patterns, v...) } } - l.options.logger.Debugf("load items %d", len(patterns)) + l.logger.Debugf("load items %d", len(patterns)) return } diff --git a/limiter/traffic/traffic.go b/limiter/traffic/traffic.go index 6f9c2b25..b4276688 100644 --- a/limiter/traffic/traffic.go +++ b/limiter/traffic/traffic.go @@ -14,6 +14,7 @@ import ( "github.com/go-gost/core/limiter/traffic" "github.com/go-gost/core/logger" "github.com/go-gost/x/internal/loader" + xlogger "github.com/go-gost/x/logger" "github.com/patrickmn/go-cache" "github.com/yl2chen/cidranger" ) @@ -89,9 +90,10 @@ type trafficLimiter struct { // service level in/out limits inLimits *cache.Cache outLimits *cache.Cache + options options + logger logger.Logger mu sync.RWMutex cancelFunc context.CancelFunc - options options } func NewTrafficLimiter(opts ...Option) traffic.TrafficLimiter { @@ -109,14 +111,14 @@ func NewTrafficLimiter(opts ...Option) traffic.TrafficLimiter { outLimits: cache.New(defaultExpiration, cleanupInterval), options: options, cancelFunc: cancel, + logger: options.logger, + } + if lim.logger == nil { + lim.logger = xlogger.Nop() } - if err := lim.reload(ctx); err != nil { - options.logger.Warnf("reload: %v", err) - } - if lim.options.period > 0 { - go lim.periodReload(ctx) - } + go lim.periodReload(ctx) + return lim } @@ -192,8 +194,8 @@ func (l *trafficLimiter) In(ctx context.Context, key string, opts ...limiter.Opt lim = newLimiterGroup(lims...) } - if lim != nil && l.options.logger != nil { - l.options.logger.Debugf("input limit for %s: %s", key, lim) + if lim != nil && l.logger != nil { + l.logger.Debugf("input limit for %s: %s", key, lim) } return lim @@ -271,18 +273,26 @@ func (l *trafficLimiter) Out(ctx context.Context, key string, opts ...limiter.Op lim = newLimiterGroup(lims...) } - if lim != nil && l.options.logger != nil { - l.options.logger.Debugf("output limit for %s: %s", key, lim) + if lim != nil && l.logger != nil { + l.logger.Debugf("output limit for %s: %s", key, lim) } return lim } func (l *trafficLimiter) periodReload(ctx context.Context) error { + if err := l.reload(ctx); err != nil { + l.logger.Warnf("reload: %v", err) + } + period := l.options.period + if period <= 0 { + return nil + } if period < time.Second { period = time.Second } + ticker := time.NewTicker(period) defer ticker.Stop() @@ -290,7 +300,7 @@ func (l *trafficLimiter) periodReload(ctx context.Context) error { select { case <-ticker.C: if err := l.reload(ctx); err != nil { - l.options.logger.Warnf("reload: %v", err) + l.logger.Warnf("reload: %v", err) // return err } case <-ctx.Done(): @@ -481,7 +491,7 @@ func (l *trafficLimiter) load(ctx context.Context) (values map[string]limitValue if lister, ok := l.options.fileLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - l.options.logger.Warnf("file loader: %v", er) + l.logger.Warnf("file loader: %v", er) } for _, s := range list { key, in, out := l.parseLimit(l.parseLine(s)) @@ -493,7 +503,7 @@ func (l *trafficLimiter) load(ctx context.Context) (values map[string]limitValue } else { r, er := l.options.fileLoader.Load(ctx) if er != nil { - l.options.logger.Warnf("file loader: %v", er) + l.logger.Warnf("file loader: %v", er) } patterns, _ := l.parsePatterns(r) for _, s := range patterns { @@ -509,7 +519,7 @@ func (l *trafficLimiter) load(ctx context.Context) (values map[string]limitValue if lister, ok := l.options.redisLoader.(loader.Lister); ok { list, er := lister.List(ctx) if er != nil { - l.options.logger.Warnf("redis loader: %v", er) + l.logger.Warnf("redis loader: %v", er) } for _, s := range list { key, in, out := l.parseLimit(l.parseLine(s)) @@ -521,7 +531,7 @@ func (l *trafficLimiter) load(ctx context.Context) (values map[string]limitValue } else { r, er := l.options.redisLoader.Load(ctx) if er != nil { - l.options.logger.Warnf("redis loader: %v", er) + l.logger.Warnf("redis loader: %v", er) } patterns, _ := l.parsePatterns(r) for _, s := range patterns { @@ -536,7 +546,7 @@ func (l *trafficLimiter) load(ctx context.Context) (values map[string]limitValue if l.options.httpLoader != nil { r, er := l.options.httpLoader.Load(ctx) if er != nil { - l.options.logger.Warnf("http loader: %v", er) + l.logger.Warnf("http loader: %v", er) } patterns, _ := l.parsePatterns(r) for _, s := range patterns { @@ -548,7 +558,7 @@ func (l *trafficLimiter) load(ctx context.Context) (values map[string]limitValue } } - l.options.logger.Debugf("load items %d", len(values)) + l.logger.Debugf("load items %d", len(values)) return } diff --git a/listener/tungo/tun_darwin.go b/listener/tungo/tun_darwin.go index d1f20c92..e14b8e8e 100644 --- a/listener/tungo/tun_darwin.go +++ b/listener/tungo/tun_darwin.go @@ -31,8 +31,14 @@ func (l *tunListener) createTun() (ifce io.ReadWriteCloser, name string, ip net. cmd := fmt.Sprintf("ifconfig %s inet %s %s mtu %d up", name, l.md.config.Net[0].String(), peer, l.md.config.MTU) l.log.Debug(cmd) + args := strings.Split(cmd, " ") - if err = exec.Command(args[0], args[1:]...).Run(); err != nil { + output, er := exec.Command(args[0], args[1:]...).CombinedOutput() + if len(output) > 0 { + l.log.Debugf("%s: %s", cmd, string(output)) + } + if er != nil { + err = fmt.Errorf("%s: %v", cmd, er) return } ip = l.md.config.Net[0].IP @@ -50,8 +56,12 @@ func (l *tunListener) addRoutes(ifName string) error { cmd := fmt.Sprintf("route add -net %s -interface %s", route.Net.String(), ifName) l.log.Debug(cmd) args := strings.Split(cmd, " ") - if err := exec.Command(args[0], args[1:]...).Run(); err != nil { - return err + output, er := exec.Command(args[0], args[1:]...).CombinedOutput() + if len(output) > 0 { + l.log.Debugf("%s: %s", cmd, string(output)) + } + if er != nil { + return fmt.Errorf("%s: %v", cmd, er) } } return nil diff --git a/listener/tungo/tun_linux.go b/listener/tungo/tun_linux.go index cac510aa..5d61d66a 100644 --- a/listener/tungo/tun_linux.go +++ b/listener/tungo/tun_linux.go @@ -64,7 +64,11 @@ func (l *tunListener) createTun() (dev io.ReadWriteCloser, name string, ip net.I l.log.Debug(cmd) args := strings.Split(cmd, " ") - if er := exec.Command(args[0], args[1:]...).Run(); er != nil { + output, er := exec.Command(args[0], args[1:]...).CombinedOutput() + if len(output) > 0 { + l.log.Debugf("%s: %s", cmd, string(output)) + } + if er != nil { err = fmt.Errorf("%s: %v", cmd, er) return } diff --git a/listener/tungo/tun_other.go b/listener/tungo/tun_other.go index a2a5c85d..8bab9a6f 100644 --- a/listener/tungo/tun_other.go +++ b/listener/tungo/tun_other.go @@ -31,7 +31,11 @@ func (l *tunListener) createTun() (ifce io.ReadWriteCloser, name string, ip net. l.log.Debug(cmd) args := strings.Split(cmd, " ") - if er := exec.Command(args[0], args[1:]...).Run(); er != nil { + output, er := exec.Command(args[0], args[1:]...).CombinedOutput() + if len(output) > 0 { + l.log.Debugf("%s: %s", cmd, string(output)) + } + if er != nil { err = fmt.Errorf("%s: %v", cmd, er) return } @@ -50,7 +54,11 @@ func (l *tunListener) addRoutes(ifName string) error { cmd := fmt.Sprintf("route add -net %s -interface %s", route.Net.String(), ifName) l.log.Debug(cmd) args := strings.Split(cmd, " ") - if er := exec.Command(args[0], args[1:]...).Run(); er != nil { + output, er := exec.Command(args[0], args[1:]...).CombinedOutput() + if len(output) > 0 { + l.log.Debugf("%s: %s", cmd, string(output)) + } + if er != nil { return fmt.Errorf("%s: %v", cmd, er) } } diff --git a/listener/tungo/tun_windows.go b/listener/tungo/tun_windows.go index 74494191..402be418 100644 --- a/listener/tungo/tun_windows.go +++ b/listener/tungo/tun_windows.go @@ -40,12 +40,16 @@ func (l *tunListener) createTun() (ifce io.ReadWriteCloser, name string, ip net. return } - if l.md.config.MTU > 0 { + if l.md.config.MTU > 0 { cmd := fmt.Sprintf("netsh interface ip set subinterface %s mtu=%d", name, l.md.config.MTU) l.log.Debug(cmd) args := strings.Split(cmd, " ") - if er := exec.Command(args[0], args[1:]...).Run(); er != nil { + output, er := exec.Command(args[0], args[1:]...).CombinedOutput() + if len(output) > 0 { + l.log.Debugf("%s: %s", cmd, windows.ByteSliceToString(output)) + } + if er != nil { err = fmt.Errorf("%s: %v", cmd, er) return } @@ -59,7 +63,11 @@ func (l *tunListener) createTun() (ifce io.ReadWriteCloser, name string, ip net. l.log.Debug(cmd) args := strings.Split(cmd, " ") - if er := exec.Command(args[0], args[1:]...).Run(); er != nil { + output, er := exec.Command(args[0], args[1:]...).CombinedOutput() + if len(output) > 0 { + l.log.Debugf("%s: %s", cmd, windows.ByteSliceToString(output)) + } + if er != nil { err = fmt.Errorf("%s: %v", cmd, er) return } @@ -75,7 +83,11 @@ func (l *tunListener) createTun() (ifce io.ReadWriteCloser, name string, ip net. l.log.Debug(cmd) args := strings.Split(cmd, " ") - if er := exec.Command(args[0], args[1:]...).Run(); er != nil { + output, er := exec.Command(args[0], args[1:]...).CombinedOutput() + if len(output) > 0 { + l.log.Debugf("%s: %s", cmd, windows.ByteSliceToString(output)) + } + if er != nil { err = fmt.Errorf("%s: %v", cmd, er) return } @@ -95,7 +107,11 @@ func (l *tunListener) addRoutes(ifName string, gw net.IP) error { } l.log.Debug(cmd) args := strings.Split(cmd, " ") - if er := exec.Command(args[0], args[1:]...).Run(); er != nil { + output, er := exec.Command(args[0], args[1:]...).CombinedOutput() + if len(output) > 0 { + l.log.Debugf("%s: %s", cmd, windows.ByteSliceToString(output)) + } + if er != nil { return fmt.Errorf("%s: %v", cmd, er) } } @@ -107,7 +123,14 @@ func (l *tunListener) deleteRoute(ifName string, route string) error { route, ifName) l.log.Debug(cmd) args := strings.Split(cmd, " ") - return exec.Command(args[0], args[1:]...).Run() + output, er := exec.Command(args[0], args[1:]...).CombinedOutput() + if len(output) > 0 { + l.log.Debugf("%s: %s", cmd, windows.ByteSliceToString(output)) + } + if er != nil { + return fmt.Errorf("%s: %v", cmd, er) + } + return nil } func ipMask(mask net.IPMask) string { diff --git a/service/service.go b/service/service.go index 68b61d17..772cf370 100644 --- a/service/service.go +++ b/service/service.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "net" + "os" "os/exec" "strings" "sync" @@ -326,8 +327,8 @@ func (s *defaultService) execCmd(cmd string) error { return errors.New("invalid command") } c := exec.Command(ss[0], ss[1:]...) - // c.Stdout = os.Stdout - // c.Stderr = os.Stderr + c.Stdout = os.Stdout + c.Stderr = os.Stderr return c.Run() }