add plugin system

This commit is contained in:
ginuerzh 2023-04-18 20:52:56 +08:00
parent 7576651a67
commit 32c8188351
48 changed files with 761 additions and 115 deletions

View File

@ -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"
"google.golang.org/grpc"
)
type options struct {
@ -21,6 +22,7 @@ type options struct {
fileLoader loader.Loader
redisLoader loader.Loader
httpLoader loader.Loader
client *grpc.ClientConn
period time.Duration
logger logger.Logger
}
@ -63,6 +65,12 @@ func HTTPLoaderOption(httpLoader loader.Loader) Option {
}
}
func PluginConnOption(c *grpc.ClientConn) Option {
return func(opts *options) {
opts.client = c
}
}
func LoggerOption(logger logger.Logger) Option {
return func(opts *options) {
opts.logger = logger
@ -101,7 +109,7 @@ func NewAdmission(opts ...Option) admission_pkg.Admission {
return p
}
func (p *admission) Admit(addr string) bool {
func (p *admission) Admit(ctx context.Context, addr string) bool {
if addr == "" || p == nil {
return true
}

56
admission/plugin.go Normal file
View File

@ -0,0 +1,56 @@
package admission
import (
"context"
admission_pkg "github.com/go-gost/core/admission"
"github.com/go-gost/plugin/admission/proto"
xlogger "github.com/go-gost/x/logger"
)
type pluginAdmission struct {
client proto.AdmissionClient
options options
}
// NewPluginAdmission creates a plugin admission.
func NewPluginAdmission(opts ...Option) admission_pkg.Admission {
var options options
for _, opt := range opts {
opt(&options)
}
if options.logger == nil {
options.logger = xlogger.Nop()
}
p := &pluginAdmission{
options: options,
}
if options.client != nil {
p.client = proto.NewAdmissionClient(options.client)
}
return p
}
func (p *pluginAdmission) Admit(ctx context.Context, addr string) bool {
if p.client == nil {
return false
}
r, err := p.client.Admit(ctx,
&proto.AdmissionRequest{
Addr: addr,
})
if err != nil {
p.options.logger.Error(err)
return false
}
return r.Ok
}
func (p *pluginAdmission) Close() error {
if p.options.client != nil {
return p.options.client.Close()
}
return nil
}

View File

@ -1,6 +1,7 @@
package wrapper
import (
"context"
"errors"
"io"
"net"
@ -33,7 +34,7 @@ func WrapConn(admission admission.Admission, c net.Conn) net.Conn {
func (c *serverConn) Read(b []byte) (n int, err error) {
if c.admission != nil &&
!c.admission.Admit(c.RemoteAddr().String()) {
!c.admission.Admit(context.Background(), c.RemoteAddr().String()) {
err = io.EOF
return
}
@ -79,7 +80,7 @@ func (c *packetConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
}
if c.admission != nil &&
!c.admission.Admit(addr.String()) {
!c.admission.Admit(context.Background(), addr.String()) {
continue
}
@ -143,7 +144,7 @@ func (c *udpConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
return
}
if c.admission != nil &&
!c.admission.Admit(addr.String()) {
!c.admission.Admit(context.Background(), addr.String()) {
continue
}
return
@ -158,7 +159,7 @@ func (c *udpConn) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) {
return
}
if c.admission != nil &&
!c.admission.Admit(addr.String()) {
!c.admission.Admit(context.Background(), addr.String()) {
continue
}
return
@ -176,7 +177,7 @@ func (c *udpConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAd
return
}
if c.admission != nil &&
!c.admission.Admit(addr.String()) {
!c.admission.Admit(context.Background(), addr.String()) {
continue
}
return

View File

@ -1,6 +1,7 @@
package wrapper
import (
"context"
"net"
"github.com/go-gost/core/admission"
@ -28,7 +29,7 @@ func (ln *listener) Accept() (net.Conn, error) {
return nil, err
}
if ln.admission != nil &&
!ln.admission.Admit(c.RemoteAddr().String()) {
!ln.admission.Admit(context.Background(), c.RemoteAddr().String()) {
c.Close()
continue
}

View File

@ -35,7 +35,7 @@ func mwBasicAuth(auther auth.Authenticator) gin.HandlerFunc {
return
}
u, p, _ := c.Request.BasicAuth()
if !auther.Authenticate(u, p) {
if !auther.Authenticate(c, u, p) {
c.AbortWithStatus(http.StatusUnauthorized)
}
}

View File

@ -12,6 +12,7 @@ import (
"github.com/go-gost/core/logger"
"github.com/go-gost/x/internal/loader"
xlogger "github.com/go-gost/x/logger"
"google.golang.org/grpc"
)
type options struct {
@ -20,6 +21,7 @@ type options struct {
redisLoader loader.Loader
httpLoader loader.Loader
period time.Duration
client *grpc.ClientConn
logger logger.Logger
}
@ -55,6 +57,12 @@ func HTTPLoaderOption(httpLoader loader.Loader) Option {
}
}
func PluginConnOption(c *grpc.ClientConn) Option {
return func(opts *options) {
opts.client = c
}
}
func LoggerOption(logger logger.Logger) Option {
return func(opts *options) {
opts.logger = logger
@ -97,14 +105,18 @@ func NewAuthenticator(opts ...Option) auth.Authenticator {
}
// Authenticate checks the validity of the provided user-password pair.
func (p *authenticator) Authenticate(user, password string) bool {
if p == nil || len(p.kvs) == 0 {
func (p *authenticator) Authenticate(ctx context.Context, user, password string) bool {
if p == nil {
return true
}
p.mu.RLock()
defer p.mu.RUnlock()
if len(p.kvs) == 0 {
return true
}
v, ok := p.kvs[user]
return ok && (v == "" || password == v)
}

58
auth/plugin.go Normal file
View File

@ -0,0 +1,58 @@
package auth
import (
"context"
"github.com/go-gost/core/auth"
"github.com/go-gost/plugin/auth/proto"
xlogger "github.com/go-gost/x/logger"
)
type pluginAuthenticator struct {
client proto.AuthenticatorClient
options options
}
// NewPluginAuthenticator creates an Authenticator that authenticates client by plugin.
func NewPluginAuthenticator(opts ...Option) auth.Authenticator {
var options options
for _, opt := range opts {
opt(&options)
}
if options.logger == nil {
options.logger = xlogger.Nop()
}
p := &pluginAuthenticator{
options: options,
}
if options.client != nil {
p.client = proto.NewAuthenticatorClient(options.client)
}
return p
}
// Authenticate checks the validity of the provided user-password pair.
func (p *pluginAuthenticator) Authenticate(ctx context.Context, user, password string) bool {
if p.client == nil {
return false
}
r, err := p.client.Authenticate(ctx,
&proto.AuthenticateRequest{
Username: user,
Password: password,
})
if err != nil {
p.options.logger.Error(err)
return false
}
return r.Ok
}
func (p *pluginAuthenticator) Close() error {
if p.options.client != nil {
return p.options.client.Close()
}
return nil
}

View File

@ -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"
"google.golang.org/grpc"
)
type options struct {
@ -21,6 +22,7 @@ type options struct {
fileLoader loader.Loader
redisLoader loader.Loader
httpLoader loader.Loader
client *grpc.ClientConn
period time.Duration
logger logger.Logger
}
@ -63,6 +65,12 @@ func HTTPLoaderOption(httpLoader loader.Loader) Option {
}
}
func PluginConnOption(c *grpc.ClientConn) Option {
return func(opts *options) {
opts.client = c
}
}
func LoggerOption(logger logger.Logger) Option {
return func(opts *options) {
opts.logger = logger
@ -232,7 +240,7 @@ func (bp *bypass) parsePatterns(r io.Reader) (patterns []string, err error) {
return
}
func (bp *bypass) Contains(addr string) bool {
func (bp *bypass) Contains(ctx context.Context, addr string) bool {
if addr == "" || bp == nil {
return false
}

56
bypass/plugin.go Normal file
View File

@ -0,0 +1,56 @@
package bypass
import (
"context"
bypass_pkg "github.com/go-gost/core/bypass"
"github.com/go-gost/plugin/bypass/proto"
xlogger "github.com/go-gost/x/logger"
)
type pluginBypass struct {
client proto.BypassClient
options options
}
// NewPluginBypass creates a plugin bypass.
func NewPluginBypass(opts ...Option) bypass_pkg.Bypass {
var options options
for _, opt := range opts {
opt(&options)
}
if options.logger == nil {
options.logger = xlogger.Nop()
}
p := &pluginBypass{
options: options,
}
if options.client != nil {
p.client = proto.NewBypassClient(options.client)
}
return p
}
func (p *pluginBypass) Contains(ctx context.Context, addr string) bool {
if p.client == nil {
return false
}
r, err := p.client.Bypass(ctx,
&proto.BypassRequest{
Addr: addr,
})
if err != nil {
p.options.logger.Error(err)
return false
}
return r.Ok
}
func (p *pluginBypass) Close() error {
if p.options.client != nil {
return p.options.client.Close()
}
return nil
}

View File

@ -74,7 +74,7 @@ func (p *chainHop) Select(ctx context.Context, opts ...chain.SelectOption) *chai
// hop level bypass
if p.options.bypass != nil &&
p.options.bypass.Contains(options.Addr) {
p.options.bypass.Contains(ctx, options.Addr) {
return nil
}
@ -121,7 +121,7 @@ func (p *chainHop) Select(ctx context.Context, opts ...chain.SelectOption) *chai
}
// node level bypass
if node.Options().Bypass != nil &&
node.Options().Bypass.Contains(options.Addr) {
node.Options().Bypass.Contains(ctx, options.Addr) {
continue
}

View File

@ -109,13 +109,19 @@ type TLSConfig struct {
Organization string `yaml:",omitempty" json:"organization,omitempty"`
}
type PluginConfig struct {
Addr string `json:"addr"`
TLS *TLSConfig `json:"tls"`
}
type AutherConfig struct {
Name string `json:"name"`
Auths []*AuthConfig `yaml:",omitempty" json:"auths"`
Auths []*AuthConfig `yaml:",omitempty" json:"auths,omitempty"`
Reload time.Duration `yaml:",omitempty" json:"reload,omitempty"`
File *FileLoader `yaml:",omitempty" json:"file,omitempty"`
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
}
type AuthConfig struct {
@ -134,11 +140,12 @@ type AdmissionConfig struct {
// DEPRECATED by whitelist since beta.4
Reverse bool `yaml:",omitempty" json:"reverse,omitempty"`
Whitelist bool `yaml:",omitempty" json:"whitelist,omitempty"`
Matchers []string `json:"matchers"`
Matchers []string `yaml:",omitempty" json:"matchers,omitempty"`
Reload time.Duration `yaml:",omitempty" json:"reload,omitempty"`
File *FileLoader `yaml:",omitempty" json:"file,omitempty"`
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
}
type BypassConfig struct {
@ -146,11 +153,12 @@ type BypassConfig struct {
// DEPRECATED by whitelist since beta.4
Reverse bool `yaml:",omitempty" json:"reverse,omitempty"`
Whitelist bool `yaml:",omitempty" json:"whitelist,omitempty"`
Matchers []string `json:"matchers"`
Matchers []string `yaml:",omitempty" json:"matchers,omitempty"`
Reload time.Duration `yaml:",omitempty" json:"reload,omitempty"`
File *FileLoader `yaml:",omitempty" json:"file,omitempty"`
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
}
type FileLoader struct {
@ -182,7 +190,8 @@ type NameserverConfig struct {
type ResolverConfig struct {
Name string `json:"name"`
Nameservers []*NameserverConfig `json:"nameservers"`
Nameservers []*NameserverConfig `yaml:",omitempty" json:"nameservers,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
}
type HostMappingConfig struct {
@ -193,11 +202,12 @@ type HostMappingConfig struct {
type HostsConfig struct {
Name string `json:"name"`
Mappings []*HostMappingConfig `json:"mappings"`
Mappings []*HostMappingConfig `yaml:",omitempty" json:"mappings,omitempty"`
Reload time.Duration `yaml:",omitempty" json:"reload,omitempty"`
File *FileLoader `yaml:",omitempty" json:"file,omitempty"`
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
}
type IngressRuleConfig struct {
@ -212,12 +222,14 @@ type IngressConfig struct {
File *FileLoader `yaml:",omitempty" json:"file,omitempty"`
Redis *RedisLoader `yaml:",omitempty" json:"redis,omitempty"`
HTTP *HTTPLoader `yaml:"http,omitempty" json:"http,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
}
type RecorderConfig struct {
Name string `json:"name"`
File *FileRecorder `yaml:",omitempty" json:"file,omitempty"`
Redis *RedisRecorder `yaml:",omitempty" json:"redis,omitempty"`
Name string `json:"name"`
File *FileRecorder `yaml:",omitempty" json:"file,omitempty"`
Redis *RedisRecorder `yaml:",omitempty" json:"redis,omitempty"`
Plugin *PluginConfig `yaml:",omitempty" json:"plugin,omitempty"`
}
type FileRecorder struct {

View File

@ -1,6 +1,7 @@
package parsing
import (
"crypto/tls"
"net"
"net/url"
@ -31,6 +32,10 @@ import (
"github.com/go-gost/x/registry"
resolver_impl "github.com/go-gost/x/resolver"
xs "github.com/go-gost/x/selector"
"google.golang.org/grpc"
"google.golang.org/grpc/backoff"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
)
const (
@ -50,6 +55,20 @@ func ParseAuther(cfg *config.AutherConfig) auth.Authenticator {
return nil
}
if cfg.Plugin != nil {
c, err := newPluginConn(cfg.Plugin)
if err != nil {
logger.Default().Error(err)
}
return auth_impl.NewPluginAuthenticator(
auth_impl.PluginConnOption(c),
auth_impl.LoggerOption(logger.Default().WithFields(map[string]any{
"kind": "auther",
"auther": cfg.Name,
})),
)
}
m := make(map[string]string)
for _, user := range cfg.Auths {
@ -84,7 +103,6 @@ func ParseAuther(cfg *config.AutherConfig) auth.Authenticator {
loader.TimeoutHTTPLoaderOption(cfg.HTTP.Timeout),
)))
}
return auth_impl.NewAuthenticator(opts...)
}
@ -170,6 +188,21 @@ func ParseAdmission(cfg *config.AdmissionConfig) admission.Admission {
if cfg == nil {
return nil
}
if cfg.Plugin != nil {
c, err := newPluginConn(cfg.Plugin)
if err != nil {
logger.Default().Error(err)
}
return admission_impl.NewPluginAdmission(
admission_impl.PluginConnOption(c),
admission_impl.LoggerOption(logger.Default().WithFields(map[string]any{
"kind": "admission",
"admission": cfg.Name,
})),
)
}
opts := []admission_impl.Option{
admission_impl.MatchersOption(cfg.Matchers),
admission_impl.WhitelistOption(cfg.Reverse || cfg.Whitelist),
@ -205,6 +238,20 @@ func ParseBypass(cfg *config.BypassConfig) bypass.Bypass {
return nil
}
if cfg.Plugin != nil {
c, err := newPluginConn(cfg.Plugin)
if err != nil {
logger.Default().Error(err)
}
return bypass_impl.NewPluginBypass(
bypass_impl.PluginConnOption(c),
bypass_impl.LoggerOption(logger.Default().WithFields(map[string]any{
"kind": "bypass",
"bypass": cfg.Name,
})),
)
}
opts := []bypass_impl.Option{
bypass_impl.MatchersOption(cfg.Matchers),
bypass_impl.WhitelistOption(cfg.Reverse || cfg.Whitelist),
@ -239,6 +286,22 @@ func ParseResolver(cfg *config.ResolverConfig) (resolver.Resolver, error) {
if cfg == nil {
return nil, nil
}
if cfg.Plugin != nil {
c, err := newPluginConn(cfg.Plugin)
if err != nil {
logger.Default().Error(err)
return nil, err
}
return resolver_impl.NewPluginResolver(
resolver_impl.PluginConnOption(c),
resolver_impl.LoggerOption(logger.Default().WithFields(map[string]any{
"kind": "resolver",
"resolver": cfg.Name,
})),
)
}
var nameservers []resolver_impl.NameServer
for _, server := range cfg.Nameservers {
nameservers = append(nameservers, resolver_impl.NameServer{
@ -254,7 +317,7 @@ func ParseResolver(cfg *config.ResolverConfig) (resolver.Resolver, error) {
return resolver_impl.NewResolver(
nameservers,
resolver_impl.LoggerResolverOption(
resolver_impl.LoggerOption(
logger.Default().WithFields(map[string]any{
"kind": "resolver",
"resolver": cfg.Name,
@ -268,6 +331,20 @@ func ParseHosts(cfg *config.HostsConfig) hosts.HostMapper {
return nil
}
if cfg.Plugin != nil {
c, err := newPluginConn(cfg.Plugin)
if err != nil {
logger.Default().Error(err)
}
return xhosts.NewPluginHostMapper(
xhosts.PluginConnOption(c),
xhosts.LoggerOption(logger.Default().WithFields(map[string]any{
"kind": "hosts",
"hosts": cfg.Name,
})),
)
}
var mappings []xhosts.Mapping
for _, mapping := range cfg.Mappings {
if mapping.IP == "" || mapping.Hostname == "" {
@ -326,6 +403,20 @@ func ParseIngress(cfg *config.IngressConfig) ingress.Ingress {
return nil
}
if cfg.Plugin != nil {
c, err := newPluginConn(cfg.Plugin)
if err != nil {
logger.Default().Error(err)
}
return xingress.NewPluginIngress(
xingress.PluginConnOption(c),
xingress.LoggerOption(logger.Default().WithFields(map[string]any{
"kind": "ingress",
"ingress": cfg.Name,
})),
)
}
var rules []xingress.Rule
for _, rule := range cfg.Rules {
if rule.Hostname == "" || rule.Endpoint == "" {
@ -380,9 +471,24 @@ func ParseRecorder(cfg *config.RecorderConfig) (r recorder.Recorder) {
return nil
}
if cfg.Plugin != nil {
c, err := newPluginConn(cfg.Plugin)
if err != nil {
logger.Default().Error(err)
}
return xrecorder.NewPluginRecorder(
xrecorder.PluginConnOption(c),
xrecorder.LoggerOption(logger.Default().WithFields(map[string]any{
"kind": "recorder",
"recorder": cfg.Name,
})),
)
}
if cfg.File != nil && cfg.File.Path != "" {
return xrecorder.FileRecorder(cfg.File.Path,
xrecorder.SepRecorderOption(cfg.File.Sep))
xrecorder.SepRecorderOption(cfg.File.Sep),
)
}
if cfg.Redis != nil &&
@ -566,3 +672,24 @@ func ParseRateLimiter(cfg *config.LimiterConfig) (lim rate.RateLimiter) {
return xrate.NewRateLimiter(opts...)
}
func newPluginConn(cfg *config.PluginConfig) (*grpc.ClientConn, error) {
grpcOpts := []grpc.DialOption{
// grpc.WithBlock(),
grpc.WithConnectParams(grpc.ConnectParams{
Backoff: backoff.DefaultConfig,
}),
grpc.FailOnNonTempDialError(true),
}
if tlsCfg := cfg.TLS; tlsCfg != nil && tlsCfg.Secure {
grpcOpts = append(grpcOpts,
grpc.WithAuthority(tlsCfg.ServerName),
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
ServerName: tlsCfg.ServerName,
InsecureSkipVerify: !tlsCfg.Secure,
})))
} else {
grpcOpts = append(grpcOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
}
return grpc.Dial(cfg.Addr, grpcOpts...)
}

21
go.mod
View File

@ -7,9 +7,10 @@ require (
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/gin-contrib/cors v1.3.1
github.com/gin-gonic/gin v1.8.2
github.com/go-gost/core v0.0.0-20230131100536-f3482d7cd848
github.com/go-gost/core v0.0.0-20230418124644-a2115a3d3876
github.com/go-gost/gosocks4 v0.0.1
github.com/go-gost/gosocks5 v0.3.1-0.20211109033403-d894d75b7f09
github.com/go-gost/plugin v0.0.0-20230418123101-d221a4ec9a98
github.com/go-gost/relay v0.4.0
github.com/go-gost/tls-dissector v0.0.2-0.20220408131628-aac992c27451
github.com/go-redis/redis/v8 v8.11.5
@ -35,19 +36,19 @@ require (
github.com/xtaci/tcpraw v1.2.25
github.com/yl2chen/cidranger v1.0.2
golang.org/x/crypto v0.6.0
golang.org/x/net v0.7.0
golang.org/x/sys v0.5.0
golang.org/x/net v0.8.0
golang.org/x/sys v0.6.0
golang.org/x/time v0.3.0
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478
google.golang.org/grpc v1.51.0
google.golang.org/protobuf v1.28.1
google.golang.org/grpc v1.54.0
google.golang.org/protobuf v1.30.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/coreos/go-iptables v0.5.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
@ -99,11 +100,11 @@ require (
github.com/ugorji/go/codec v1.2.7 // indirect
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
golang.org/x/exp v0.0.0-20221217163422-3c43f8badb15 // indirect
golang.org/x/mod v0.7.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/tools v0.4.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.6.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

40
go.sum
View File

@ -55,8 +55,9 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@ -91,12 +92,14 @@ github.com/gin-gonic/gin v1.8.2/go.mod h1:qw5AYuDrzRTnhvusDsrov+fDIxp9Dleuu12h8n
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gost/core v0.0.0-20230131100536-f3482d7cd848 h1:jAack881fzd5s1jNC5w9SK1gL3bvnh4iK1lMFPnjUw8=
github.com/go-gost/core v0.0.0-20230131100536-f3482d7cd848/go.mod h1:R08B7BVdhWsYHX8s7wkEBpeKqc4+YFP6bLLFoao0J/A=
github.com/go-gost/core v0.0.0-20230418124644-a2115a3d3876 h1:SnrPPRt+IEHhxWmVwsiVu8yrfM8TS8ItYG3WRR5P/7c=
github.com/go-gost/core v0.0.0-20230418124644-a2115a3d3876/go.mod h1:pKIGDCHZSnxTUmBNMjVogJ+EjUdvaRdqMIJzQhEVOGQ=
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.3.1-0.20211109033403-d894d75b7f09 h1:A95M6UWcfZgOuJkQ7QLfG0Hs5peWIUSysCDNz4pfe04=
github.com/go-gost/gosocks5 v0.3.1-0.20211109033403-d894d75b7f09/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4=
github.com/go-gost/plugin v0.0.0-20230418123101-d221a4ec9a98 h1:dOtNcxZbMDwtowa8b91nK2JcTL1lG0EIv0sXqSbvTc4=
github.com/go-gost/plugin v0.0.0-20230418123101-d221a4ec9a98/go.mod h1:IGQawP0E9B36VZ0AfDOpBK23bW4rOSiHtnU7mtafpAM=
github.com/go-gost/relay v0.4.0 h1:zSOqJqnwV63oRiQ6fuurDYvehAVi3PizzFeE1gT+qo4=
github.com/go-gost/relay v0.4.0/go.mod h1:lcX+23LCQ3khIeASBo+tJ/WbwXFO32/N5YN6ucuYTG8=
github.com/go-gost/tls-dissector v0.0.2-0.20220408131628-aac992c27451 h1:xj8gUZGYO3nb5+6Bjw9+tsFkA9sYynrOvDvvC4uDV2I=
@ -464,8 +467,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -507,8 +510,9 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -591,14 +595,15 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -608,8 +613,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -667,8 +673,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -739,8 +745,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y=
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -757,8 +763,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -771,8 +777,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -194,7 +194,7 @@ func (h *dnsHandler) request(ctx context.Context, msg []byte, log logger.Logger)
}
if h.options.Bypass != nil && mq.Question[0].Qclass == dns.ClassINET {
if h.options.Bypass.Contains(strings.Trim(mq.Question[0].Name, ".")) {
if h.options.Bypass.Contains(context.Background(), strings.Trim(mq.Question[0].Name, ".")) {
log.Debug("bypass: ", mq.Question[0].Name)
mr = (&dns.Msg{}).SetReply(&mq)
b := bufpool.Get(h.md.bufferSize)
@ -202,7 +202,7 @@ func (h *dnsHandler) request(ctx context.Context, msg []byte, log logger.Logger)
}
}
mr = h.lookupHosts(&mq, log)
mr = h.lookupHosts(ctx, &mq, log)
if mr != nil {
b := bufpool.Get(h.md.bufferSize)
return mr.PackBuffer(*b)
@ -272,7 +272,7 @@ func (h *dnsHandler) exchange(ctx context.Context, mq *dns.Msg) ([]byte, error)
}
// lookup host mapper
func (h *dnsHandler) lookupHosts(r *dns.Msg, log logger.Logger) (m *dns.Msg) {
func (h *dnsHandler) lookupHosts(ctx context.Context, r *dns.Msg, log logger.Logger) (m *dns.Msg) {
if h.hostMapper == nil ||
r.Question[0].Qclass != dns.ClassINET ||
(r.Question[0].Qtype != dns.TypeA && r.Question[0].Qtype != dns.TypeAAAA) {
@ -286,7 +286,7 @@ func (h *dnsHandler) lookupHosts(r *dns.Msg, log logger.Logger) (m *dns.Msg) {
switch r.Question[0].Qtype {
case dns.TypeA:
ips, _ := h.hostMapper.Lookup("ip4", host)
ips, _ := h.hostMapper.Lookup(ctx, "ip4", host)
if len(ips) == 0 {
return nil
}
@ -302,7 +302,7 @@ func (h *dnsHandler) lookupHosts(r *dns.Msg, log logger.Logger) (m *dns.Msg) {
}
case dns.TypeAAAA:
ips, _ := h.hostMapper.Lookup("ip6", host)
ips, _ := h.hostMapper.Lookup(ctx, "ip6", host)
if len(ips) == 0 {
return nil
}

View File

@ -202,7 +202,7 @@ func (h *forwardHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, log l
if auther := target.Options().Auther; auther != nil {
username, password, _ := req.BasicAuth()
if !auther.Authenticate(username, password) {
if !auther.Authenticate(ctx, username, password) {
resp.StatusCode = http.StatusUnauthorized
resp.Header.Set("WWW-Authenticate", "Basic")
log.Warnf("node %s(%s) 401 unauthorized", target.Name, target.Addr)

View File

@ -199,7 +199,7 @@ func (h *forwardHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, log l
if auther := target.Options().Auther; auther != nil {
username, password, _ := req.BasicAuth()
if !auther.Authenticate(username, password) {
if !auther.Authenticate(ctx, username, password) {
resp.StatusCode = http.StatusUnauthorized
resp.Header.Set("WWW-Authenticate", "Basic")
log.Warnf("node %s(%s) 401 unauthorized", target.Name, target.Addr)

View File

@ -145,7 +145,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
resp.Header = http.Header{}
}
if h.options.Bypass != nil && h.options.Bypass.Contains(addr) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, addr) {
resp.StatusCode = http.StatusForbidden
if log.IsLevelEnabled(logger.TraceLevel) {
@ -157,7 +157,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
return resp.Write(conn)
}
if !h.authenticate(conn, req, resp, log) {
if !h.authenticate(ctx, conn, req, resp, log) {
return nil
}
@ -266,9 +266,9 @@ func (h *httpHandler) basicProxyAuth(proxyAuth string, log logger.Logger) (usern
return cs[:s], cs[s+1:], true
}
func (h *httpHandler) authenticate(conn net.Conn, req *http.Request, resp *http.Response, log logger.Logger) (ok bool) {
func (h *httpHandler) authenticate(ctx context.Context, conn net.Conn, req *http.Request, resp *http.Response, log logger.Logger) (ok bool) {
u, p, _ := h.basicProxyAuth(req.Header.Get("Proxy-Authorization"), log)
if h.options.Auther == nil || h.options.Auther.Authenticate(u, p) {
if h.options.Auther == nil || h.options.Auther.Authenticate(ctx, u, p) {
return true
}

View File

@ -139,7 +139,7 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
w.Header().Set(k, h.md.header.Get(k))
}
if h.options.Bypass != nil && h.options.Bypass.Contains(addr) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, addr) {
w.WriteHeader(http.StatusForbidden)
log.Debug("bypass: ", addr)
return nil
@ -152,7 +152,7 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
}
if !h.authenticate(w, req, resp, log) {
if !h.authenticate(ctx, w, req, resp, log) {
return nil
}
@ -252,9 +252,9 @@ func (h *http2Handler) basicProxyAuth(proxyAuth string) (username, password stri
return cs[:s], cs[s+1:], true
}
func (h *http2Handler) authenticate(w http.ResponseWriter, r *http.Request, resp *http.Response, log logger.Logger) (ok bool) {
func (h *http2Handler) authenticate(ctx context.Context, w http.ResponseWriter, r *http.Request, resp *http.Response, log logger.Logger) (ok bool) {
u, p, _ := h.basicProxyAuth(r.Header.Get("Proxy-Authorization"))
if h.options.Auther == nil || h.options.Auther.Authenticate(u, p) {
if h.options.Auther == nil || h.options.Auther.Authenticate(ctx, u, p) {
return true
}

View File

@ -105,7 +105,7 @@ func (h *http3Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
w.Header().Set(k, h.md.header.Get(k))
}
if h.options.Bypass != nil && h.options.Bypass.Contains(addr) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, addr) {
w.WriteHeader(http.StatusForbidden)
log.Debug("bypass: ", addr)
return nil

View File

@ -116,7 +116,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
log.Debugf("%s >> %s", conn.RemoteAddr(), dstAddr)
if h.options.Bypass != nil && h.options.Bypass.Contains(dstAddr.String()) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, dstAddr.String()) {
log.Debug("bypass: ", dstAddr)
return nil
}
@ -157,7 +157,7 @@ func (h *redirectHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, radd
"host": host,
})
if h.options.Bypass != nil && h.options.Bypass.Contains(host) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, host) {
log.Debug("bypass: ", host)
return nil
}
@ -226,7 +226,7 @@ func (h *redirectHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, rad
"host": host,
})
if h.options.Bypass != nil && h.options.Bypass.Contains(host) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, host) {
log.Debug("bypass: ", host)
return nil
}

View File

@ -75,7 +75,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
log.Debugf("%s >> %s", conn.RemoteAddr(), dstAddr)
if h.options.Bypass != nil && h.options.Bypass.Contains(dstAddr.String()) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, dstAddr.String()) {
log.Debug("bypass: ", dstAddr)
return nil
}

View File

@ -35,7 +35,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network
return err
}
if h.options.Bypass != nil && h.options.Bypass.Contains(address) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, address) {
log.Debug("bypass: ", address)
resp.Status = relay.StatusForbidden
_, err := resp.WriteTo(conn)
@ -112,7 +112,7 @@ func (h *relayHandler) handleConnectTunnel(ctx context.Context, conn net.Conn, n
host, sp, _ := net.SplitHostPort(address)
if h.options.Bypass != nil && h.options.Bypass.Contains(address) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, address) {
log.Debug("bypass: ", address)
resp.Status = relay.StatusForbidden
_, err := resp.WriteTo(conn)
@ -121,7 +121,7 @@ func (h *relayHandler) handleConnectTunnel(ctx context.Context, conn net.Conn, n
var tid relay.TunnelID
if ingress := h.md.ingress; ingress != nil {
tid = parseTunnelID(ingress.Get(host))
tid = parseTunnelID(ingress.Get(ctx, host))
}
if !tid.Equal(tunnelID) && !h.md.directTunnel {
resp.Status = relay.StatusBadRequest

View File

@ -185,7 +185,7 @@ func (h *tunnelHandler) Handle(ctx context.Context, conn net.Conn, opts ...handl
var tunnelID relay.TunnelID
if h.ingress != nil {
tunnelID = parseTunnelID(h.ingress.Get(host))
tunnelID = parseTunnelID(h.ingress.Get(ctx, host))
}
if tunnelID.IsZero() {
err := fmt.Errorf("no route to host %s", host)
@ -248,7 +248,7 @@ func (h *tunnelHandler) handleHTTP(ctx context.Context, raddr net.Addr, rw io.Re
var tunnelID relay.TunnelID
if h.ingress != nil {
tunnelID = parseTunnelID(h.ingress.Get(req.Host))
tunnelID = parseTunnelID(h.ingress.Get(ctx, req.Host))
}
if tunnelID.IsZero() {
err := fmt.Errorf("no route to host %s", req.Host)

View File

@ -196,7 +196,7 @@ func (h *relayHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle
}
if h.options.Auther != nil &&
!h.options.Auther.Authenticate(user, pass) {
!h.options.Auther.Authenticate(ctx, user, pass) {
resp.Status = relay.StatusUnauthorized
resp.WriteTo(conn)
return ErrUnauthorized

View File

@ -115,7 +115,7 @@ func (h *sniHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, raddr net
"host": host,
})
if h.options.Bypass != nil && h.options.Bypass.Contains(host) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, host) {
log.Debug("bypass: ", host)
return nil
}
@ -183,7 +183,7 @@ func (h *sniHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, raddr ne
})
log.Debugf("%s >> %s", raddr, host)
if h.options.Bypass != nil && h.options.Bypass.Contains(host) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, host) {
log.Debug("bypass: ", host)
return nil
}

View File

@ -91,7 +91,7 @@ func (h *socks4Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl
conn.SetReadDeadline(time.Time{})
if h.options.Auther != nil &&
!h.options.Auther.Authenticate(string(req.Userid), "") {
!h.options.Auther.Authenticate(ctx, string(req.Userid), "") {
resp := gosocks4.NewReply(gosocks4.RejectedUserid, nil)
log.Trace(resp)
return resp.Write(conn)
@ -117,7 +117,7 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g
})
log.Debugf("%s >> %s", conn.RemoteAddr(), addr)
if h.options.Bypass != nil && h.options.Bypass.Contains(addr) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, addr) {
resp := gosocks4.NewReply(gosocks4.Rejected, nil)
log.Trace(resp)
log.Debug("bypass: ", addr)

View File

@ -19,7 +19,7 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ
})
log.Debugf("%s >> %s", conn.RemoteAddr(), address)
if h.options.Bypass != nil && h.options.Bypass.Contains(address) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, address) {
resp := gosocks5.NewReply(gosocks5.NotAllowed, nil)
log.Trace(resp)
log.Debug("bypass: ", address)

View File

@ -1,6 +1,7 @@
package v5
import (
"context"
"crypto/tls"
"net"
@ -64,7 +65,7 @@ func (s *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, erro
s.logger.Trace(req)
if s.Authenticator != nil &&
!s.Authenticator.Authenticate(req.Username, req.Password) {
!s.Authenticator.Authenticate(context.Background(), req.Username, req.Password) {
resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure)
if err := resp.Write(conn); err != nil {
s.logger.Error(err)

View File

@ -102,7 +102,7 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H
log.Debugf("%s >> %s", conn.RemoteAddr(), addr)
if h.options.Bypass != nil && h.options.Bypass.Contains(addr.String()) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, addr.String()) {
log.Debug("bypass: ", addr.String())
return nil
}

View File

@ -135,7 +135,7 @@ func (h *ssuHandler) relayPacket(pc1, pc2 net.PacketConn, log logger.Logger) (er
return err
}
if h.options.Bypass != nil && h.options.Bypass.Contains(addr.String()) {
if h.options.Bypass != nil && h.options.Bypass.Contains(context.Background(), addr.String()) {
log.Warn("bypass: ", addr)
return nil
}
@ -167,7 +167,7 @@ func (h *ssuHandler) relayPacket(pc1, pc2 net.PacketConn, log logger.Logger) (er
return err
}
if h.options.Bypass != nil && h.options.Bypass.Contains(raddr.String()) {
if h.options.Bypass != nil && h.options.Bypass.Contains(context.Background(), raddr.String()) {
log.Warn("bypass: ", raddr)
return nil
}

View File

@ -92,7 +92,7 @@ func (h *forwardHandler) handleDirectForward(ctx context.Context, conn *sshd_uti
log.Debugf("%s >> %s", conn.RemoteAddr(), targetAddr)
if h.options.Bypass != nil && h.options.Bypass.Contains(targetAddr) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, targetAddr) {
log.Debugf("bypass %s", targetAddr)
return nil
}

View File

@ -25,7 +25,7 @@ func (h *tunHandler) handleServer(ctx context.Context, conn net.Conn, config *tu
}
defer pc.Close()
return h.transportServer(conn, pc, config, log)
return h.transportServer(ctx, conn, pc, config, log)
}()
if err == ErrTun {
return err
@ -36,7 +36,7 @@ func (h *tunHandler) handleServer(ctx context.Context, conn net.Conn, config *tu
}
}
func (h *tunHandler) transportServer(tun io.ReadWriter, conn net.PacketConn, config *tun_util.Config, log logger.Logger) error {
func (h *tunHandler) transportServer(ctx context.Context, tun io.ReadWriter, conn net.PacketConn, config *tun_util.Config, log logger.Logger) error {
errc := make(chan error, 1)
go func() {
@ -135,7 +135,7 @@ func (h *tunHandler) transportServer(tun io.ReadWriter, conn net.PacketConn, con
ok := true
key := bytes.TrimRight((*b)[4:20], "\x00")
for _, ip := range peerIPs {
if ok = auther.Authenticate(ip.String(), string(key)); !ok {
if ok = auther.Authenticate(ctx, ip.String(), string(key)); !ok {
break
}
}

View File

@ -12,6 +12,7 @@ import (
"github.com/go-gost/core/hosts"
"github.com/go-gost/core/logger"
"github.com/go-gost/x/internal/loader"
"google.golang.org/grpc"
)
type Mapping struct {
@ -24,6 +25,7 @@ type options struct {
fileLoader loader.Loader
redisLoader loader.Loader
httpLoader loader.Loader
client *grpc.ClientConn
period time.Duration
logger logger.Logger
}
@ -60,6 +62,12 @@ func HTTPLoaderOption(httpLoader loader.Loader) Option {
}
}
func PluginConnOption(c *grpc.ClientConn) Option {
return func(opts *options) {
opts.client = c
}
}
func LoggerOption(logger logger.Logger) Option {
return func(opts *options) {
opts.logger = logger
@ -104,7 +112,7 @@ func NewHostMapper(opts ...Option) hosts.HostMapper {
// Lookup searches the IP address corresponds to the given network and host from the host table.
// The network should be 'ip', 'ip4' or 'ip6', default network is 'ip'.
// the host should be a hostname (example.org) or a hostname with dot prefix (.example.org).
func (h *hostMapper) Lookup(network, host string) (ips []net.IP, ok bool) {
func (h *hostMapper) Lookup(ctx context.Context, network, host string) (ips []net.IP, ok bool) {
h.options.logger.Debugf("lookup %s/%s", host, network)
ips = h.lookup(host)
if ips == nil {

66
hosts/plugin.go Normal file
View File

@ -0,0 +1,66 @@
package hosts
import (
"context"
"net"
"github.com/go-gost/core/hosts"
"github.com/go-gost/plugin/hosts/proto"
xlogger "github.com/go-gost/x/logger"
)
type pluginHostMapper struct {
client proto.HostMapperClient
options options
}
// NewPluginHostMapper creates a plugin HostMapper.
func NewPluginHostMapper(opts ...Option) hosts.HostMapper {
var options options
for _, opt := range opts {
opt(&options)
}
if options.logger == nil {
options.logger = xlogger.Nop()
}
p := &pluginHostMapper{
options: options,
}
if options.client != nil {
p.client = proto.NewHostMapperClient(options.client)
}
return p
}
func (p *pluginHostMapper) Lookup(ctx context.Context, network, host string) (ips []net.IP, ok bool) {
p.options.logger.Debugf("lookup %s/%s", host, network)
if p.client == nil {
return
}
r, err := p.client.Lookup(ctx,
&proto.LookupRequest{
Network: network,
Host: host,
})
if err != nil {
p.options.logger.Error(err)
return
}
for _, s := range r.Ips {
if ip := net.ParseIP(s); ip != nil {
ips = append(ips, ip)
}
}
ok = r.Ok
return
}
func (p *pluginHostMapper) Close() error {
if p.options.client != nil {
return p.options.client.Close()
}
return nil
}

View File

@ -12,6 +12,7 @@ import (
ingress_pkg "github.com/go-gost/core/ingress"
"github.com/go-gost/core/logger"
"github.com/go-gost/x/internal/loader"
"google.golang.org/grpc"
)
type Rule struct {
@ -24,6 +25,7 @@ type options struct {
fileLoader loader.Loader
redisLoader loader.Loader
httpLoader loader.Loader
client *grpc.ClientConn
period time.Duration
logger logger.Logger
}
@ -60,6 +62,12 @@ func HTTPLoaderOption(httpLoader loader.Loader) Option {
}
}
func PluginConnOption(c *grpc.ClientConn) Option {
return func(opts *options) {
opts.client = c
}
}
func LoggerOption(logger logger.Logger) Option {
return func(opts *options) {
opts.logger = logger
@ -219,7 +227,7 @@ func (ing *ingress) parseRules(r io.Reader) (rules []Rule, err error) {
return
}
func (ing *ingress) Get(host string) string {
func (ing *ingress) Get(ctx context.Context, host string) string {
if host == "" || ing == nil {
return ""
}

56
ingress/plugin.go Normal file
View File

@ -0,0 +1,56 @@
package ingress
import (
"context"
ingress_pkg "github.com/go-gost/core/ingress"
"github.com/go-gost/plugin/ingress/proto"
xlogger "github.com/go-gost/x/logger"
)
type pluginIngress struct {
client proto.IngressClient
options options
}
// NewPluginIngress creates a plugin ingress.
func NewPluginIngress(opts ...Option) ingress_pkg.Ingress {
var options options
for _, opt := range opts {
opt(&options)
}
if options.logger == nil {
options.logger = xlogger.Nop()
}
p := &pluginIngress{
options: options,
}
if options.client != nil {
p.client = proto.NewIngressClient(options.client)
}
return p
}
func (p *pluginIngress) Get(ctx context.Context, host string) string {
if p.client == nil {
return ""
}
r, err := p.client.Get(ctx,
&proto.GetRequest{
Host: host,
})
if err != nil {
p.options.logger.Error(err)
return ""
}
return r.GetEndpoint()
}
func (p *pluginIngress) Close() error {
if p.options.client != nil {
return p.options.client.Close()
}
return nil
}

View File

@ -1,6 +1,7 @@
package udp
import (
"context"
"net"
"github.com/go-gost/core/bypass"
@ -57,7 +58,7 @@ func (r *Relay) Run() (err error) {
return err
}
if r.bypass != nil && r.bypass.Contains(raddr.String()) {
if r.bypass != nil && r.bypass.Contains(context.Background(), raddr.String()) {
if r.logger != nil {
r.logger.Warn("bypass: ", raddr)
}
@ -95,7 +96,7 @@ func (r *Relay) Run() (err error) {
return err
}
if r.bypass != nil && r.bypass.Contains(raddr.String()) {
if r.bypass != nil && r.bypass.Contains(context.Background(), raddr.String()) {
if r.logger != nil {
r.logger.Warn("bypass: ", raddr)
}

View File

@ -1,6 +1,7 @@
package ssh
import (
"context"
"errors"
"fmt"
"io/ioutil"
@ -26,7 +27,7 @@ func PasswordCallback(au auth.Authenticator) PasswordCallbackFunc {
return nil
}
return func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
if au.Authenticate(conn.User(), string(password)) {
if au.Authenticate(context.Background(), conn.User(), string(password)) {
return nil, nil
}
return nil, fmt.Errorf("password rejected for %s", conn.User())

77
recorder/plugin.go Normal file
View File

@ -0,0 +1,77 @@
package recorder
import (
"context"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/recorder"
"github.com/go-gost/plugin/recorder/proto"
xlogger "github.com/go-gost/x/logger"
"google.golang.org/grpc"
)
type pluginOptions struct {
client *grpc.ClientConn
logger logger.Logger
}
type PluginOption func(opts *pluginOptions)
func PluginConnOption(c *grpc.ClientConn) PluginOption {
return func(opts *pluginOptions) {
opts.client = c
}
}
func LoggerOption(logger logger.Logger) PluginOption {
return func(opts *pluginOptions) {
opts.logger = logger
}
}
type pluginRecorder struct {
client proto.RecorderClient
options pluginOptions
}
// NewPluginRecorder creates a plugin recorder.
func NewPluginRecorder(opts ...PluginOption) recorder.Recorder {
var options pluginOptions
for _, opt := range opts {
opt(&options)
}
if options.logger == nil {
options.logger = xlogger.Nop()
}
p := &pluginRecorder{
options: options,
}
if options.client != nil {
p.client = proto.NewRecorderClient(options.client)
}
return p
}
func (p *pluginRecorder) Record(ctx context.Context, b []byte) error {
if p.client == nil {
return nil
}
_, err := p.client.Record(context.Background(),
&proto.RecordRequest{
Data: b,
})
if err != nil {
p.options.logger.Error(err)
return err
}
return nil
}
func (p *pluginRecorder) Close() error {
if p.options.client != nil {
return p.options.client.Close()
}
return nil
}

View File

@ -1,6 +1,8 @@
package registry
import (
"context"
"github.com/go-gost/core/admission"
)
@ -28,10 +30,10 @@ type admissionWrapper struct {
r *admissionRegistry
}
func (w *admissionWrapper) Admit(addr string) bool {
func (w *admissionWrapper) Admit(ctx context.Context, addr string) bool {
p := w.r.get(w.name)
if p == nil {
return false
}
return p.Admit(addr)
return p.Admit(ctx, addr)
}

View File

@ -1,6 +1,8 @@
package registry
import (
"context"
"github.com/go-gost/core/auth"
)
@ -28,10 +30,10 @@ type autherWrapper struct {
r *autherRegistry
}
func (w *autherWrapper) Authenticate(user, password string) bool {
func (w *autherWrapper) Authenticate(ctx context.Context, user, password string) bool {
v := w.r.get(w.name)
if v == nil {
return true
}
return v.Authenticate(user, password)
return v.Authenticate(ctx, user, password)
}

View File

@ -1,6 +1,8 @@
package registry
import (
"context"
"github.com/go-gost/core/bypass"
)
@ -28,10 +30,10 @@ type bypassWrapper struct {
r *bypassRegistry
}
func (w *bypassWrapper) Contains(addr string) bool {
func (w *bypassWrapper) Contains(ctx context.Context, addr string) bool {
bp := w.r.get(w.name)
if bp == nil {
return false
}
return bp.Contains(addr)
return bp.Contains(ctx, addr)
}

View File

@ -1,6 +1,7 @@
package registry
import (
"context"
"net"
"github.com/go-gost/core/hosts"
@ -30,10 +31,10 @@ type hostsWrapper struct {
r *hostsRegistry
}
func (w *hostsWrapper) Lookup(network, host string) ([]net.IP, bool) {
func (w *hostsWrapper) Lookup(ctx context.Context, network, host string) ([]net.IP, bool) {
v := w.r.get(w.name)
if v == nil {
return nil, false
}
return v.Lookup(network, host)
return v.Lookup(ctx, network, host)
}

View File

@ -1,6 +1,8 @@
package registry
import (
"context"
"github.com/go-gost/core/ingress"
)
@ -28,10 +30,10 @@ type ingressWrapper struct {
r *ingressRegistry
}
func (w *ingressWrapper) Get(host string) string {
func (w *ingressWrapper) Get(ctx context.Context, host string) string {
v := w.r.get(w.name)
if v == nil {
return ""
}
return v.Get(host)
return v.Get(ctx, host)
}

65
resolver/plugin.go Normal file
View File

@ -0,0 +1,65 @@
package resolver
import (
"context"
"net"
resolver_pkg "github.com/go-gost/core/resolver"
"github.com/go-gost/plugin/resolver/proto"
xlogger "github.com/go-gost/x/logger"
)
type pluginResolver struct {
client proto.ResolverClient
options options
}
// NewPluginResolver creates a plugin Resolver.
func NewPluginResolver(opts ...Option) (resolver_pkg.Resolver, error) {
var options options
for _, opt := range opts {
opt(&options)
}
if options.logger == nil {
options.logger = xlogger.Nop()
}
p := &pluginResolver{
options: options,
}
if options.client != nil {
p.client = proto.NewResolverClient(options.client)
}
return p, nil
}
func (p *pluginResolver) Resolve(ctx context.Context, network, host string) (ips []net.IP, err error) {
p.options.logger.Debugf("resolve %s/%s", host, network)
if p.client == nil {
return
}
r, err := p.client.Resolve(context.Background(),
&proto.ResolveRequest{
Network: network,
Host: host,
})
if err != nil {
p.options.logger.Error(err)
return
}
for _, s := range r.Ips {
if ip := net.ParseIP(s); ip != nil {
ips = append(ips, ip)
}
}
return
}
func (p *pluginResolver) Close() error {
if p.options.client != nil {
return p.options.client.Close()
}
return nil
}

View File

@ -12,6 +12,7 @@ import (
resolver_util "github.com/go-gost/x/internal/util/resolver"
"github.com/go-gost/x/resolver/exchanger"
"github.com/miekg/dns"
"google.golang.org/grpc"
)
type NameServer struct {
@ -25,21 +26,28 @@ type NameServer struct {
exchanger exchanger.Exchanger
}
type resolverOptions struct {
type options struct {
domain string
client *grpc.ClientConn
logger logger.Logger
}
type ResolverOption func(opts *resolverOptions)
type Option func(opts *options)
func DomainResolverOption(domain string) ResolverOption {
return func(opts *resolverOptions) {
func DomainOption(domain string) Option {
return func(opts *options) {
opts.domain = domain
}
}
func LoggerResolverOption(logger logger.Logger) ResolverOption {
return func(opts *resolverOptions) {
func PluginConnOption(c *grpc.ClientConn) Option {
return func(opts *options) {
opts.client = c
}
}
func LoggerOption(logger logger.Logger) Option {
return func(opts *options) {
opts.logger = logger
}
}
@ -47,11 +55,11 @@ func LoggerResolverOption(logger logger.Logger) ResolverOption {
type resolver struct {
servers []NameServer
cache *resolver_util.Cache
options resolverOptions
options options
}
func NewResolver(nameservers []NameServer, opts ...ResolverOption) (resolverpkg.Resolver, error) {
options := resolverOptions{}
func NewResolver(nameservers []NameServer, opts ...Option) (resolverpkg.Resolver, error) {
options := options{}
for _, opt := range opts {
opt(&options)
}

View File

@ -158,7 +158,7 @@ func (s *defaultService) Serve() error {
}
}
if s.options.admission != nil &&
!s.options.admission.Admit(conn.RemoteAddr().String()) {
!s.options.admission.Admit(context.Background(), conn.RemoteAddr().String()) {
conn.Close()
s.options.logger.Debugf("admission: %s is denied", conn.RemoteAddr())
continue