diff --git a/bypass/bypass.go b/bypass/bypass.go index 8b37a11..e7b99e2 100644 --- a/bypass/bypass.go +++ b/bypass/bypass.go @@ -2,10 +2,22 @@ package bypass import "context" +type Options struct { + Host string +} + +type Option func(opts *Options) + +func WithHostOpton(host string) Option { + return func(opts *Options) { + opts.Host = host + } +} + // Bypass is a filter of address (IP or domain). type Bypass interface { // Contains reports whether the bypass includes addr. - Contains(ctx context.Context, addr string) bool + Contains(ctx context.Context, network, addr string, opts ...Option) bool } type bypassGroup struct { @@ -18,9 +30,9 @@ func BypassGroup(bypasses ...Bypass) Bypass { } } -func (p *bypassGroup) Contains(ctx context.Context, addr string) bool { +func (p *bypassGroup) Contains(ctx context.Context, network, addr string, opts ...Option) bool { for _, bypass := range p.bypasses { - if bypass != nil && bypass.Contains(ctx, addr) { + if bypass != nil && bypass.Contains(ctx, network, addr, opts...) { return true } } diff --git a/chain/chain.go b/chain/chain.go index 68b88d2..56cb658 100644 --- a/chain/chain.go +++ b/chain/chain.go @@ -4,6 +4,18 @@ import ( "context" ) -type Chainer interface { - Route(ctx context.Context, network, address string) Route +type RouteOptions struct { + Host string +} + +type RouteOption func(opts *RouteOptions) + +func WithHostRouteOption(host string) RouteOption { + return func(opts *RouteOptions) { + opts.Host = host + } +} + +type Chainer interface { + Route(ctx context.Context, network, address string, opts ...RouteOption) Route } diff --git a/chain/router.go b/chain/router.go index 81674ee..62bc9b3 100644 --- a/chain/router.go +++ b/chain/router.go @@ -155,7 +155,8 @@ func (r *Router) dial(ctx context.Context, network, address string) (conn net.Co r.options.Logger.Debugf("dial %s/%s", address, network) for i := 0; i < count; i++ { - address, err = Resolve(ctx, "ip", address, r.options.Resolver, r.options.HostMapper, r.options.Logger) + var ipAddr string + ipAddr, err = Resolve(ctx, "ip", address, r.options.Resolver, r.options.HostMapper, r.options.Logger) if err != nil { r.options.Logger.Error(err) break @@ -163,7 +164,7 @@ func (r *Router) dial(ctx context.Context, network, address string) (conn net.Co var route Route if r.options.Chain != nil { - route = r.options.Chain.Route(ctx, network, address) + route = r.options.Chain.Route(ctx, network, ipAddr, WithHostRouteOption(address)) } if r.options.Logger.IsLevelEnabled(logger.DebugLevel) { @@ -171,14 +172,14 @@ func (r *Router) dial(ctx context.Context, network, address string) (conn net.Co for _, node := range routePath(route) { fmt.Fprintf(&buf, "%s@%s > ", node.Name, node.Addr) } - fmt.Fprintf(&buf, "%s", address) + fmt.Fprintf(&buf, "%s", ipAddr) r.options.Logger.Debugf("route(retry=%d) %s", i, buf.String()) } if route == nil { route = DefaultRoute } - conn, err = route.Dial(ctx, network, address, + conn, err = route.Dial(ctx, network, ipAddr, InterfaceDialOption(r.options.IfceName), SockOptsDialOption(r.options.SockOpts), LoggerDialOption(r.options.Logger), diff --git a/hop/hop.go b/hop/hop.go index ddb434a..026d0c2 100644 --- a/hop/hop.go +++ b/hop/hop.go @@ -7,6 +7,7 @@ import ( ) type SelectOptions struct { + Network string Addr string Host string Protocol string @@ -14,6 +15,12 @@ type SelectOptions struct { type SelectOption func(*SelectOptions) +func NetworkSelectOption(network string) SelectOption { + return func(so *SelectOptions) { + so.Network = network + } +} + func AddrSelectOption(addr string) SelectOption { return func(o *SelectOptions) { o.Addr = addr